Saiki778k downloadsSurface notes most semantically similar to the one you're reading in a left-sidebar panel, powered by a small multilingual embedding model that runs entirely on your machine. Private and offline.
Crisper, as MP4 · every number in it is measured, see ARCHITECTURE.md
A left-sidebar panel that surfaces the notes most semantically similar to the one you're reading, so you browse your vault by meaning, not by folders. Open any note and the panel ranks the rest by how closely they relate, as a stack of cards you can click to jump to.
It runs on a small multilingual embedding model that lives entirely on your machine: no cloud, no API key, no second app or server. After a one-time model download it works fully offline, and it understands German, English and 100+ other languages, so matches cross languages naturally.
Contents · What's new · Roadmap · What it does · How it works · Settings · Install
The plugin gained a reader: a small local text model that quietly reads your notes in the background and improves what the panel shows. It writes a one-line summary for every note (shown under the card title, with a fuller two-sentence summary on hover) and suggests tags for the active note, picked only from tags your vault already uses, shown as ghost chips you can add with one click.
Like the embeddings, it is invisible infrastructure: it works only while Obsidian is idle, pauses when you type or when indexing runs, caches everything, and re-reads a note only when its content changes. It is off by default; enabling it downloads the engine and a model sized to your machine's memory (a large, mid or small Qwen3, roughly 1 to 5 GB), stored outside the vault so sync never sees it. Everything runs on your machine through llama.cpp inside the plugin itself: no cloud, no account, no second app. On networks that block downloads there is a guided offline setup (command palette: "Reader: offline setup") that fetches the files through your browser and imports them automatically, verified against pinned checksums.
Also in 4.0: the insights report's surprising-connections section is gone. It generated a list that was rarely used; the link-graph machinery behind it stays in the ranking itself, where it earns its keep.
Ranking stopped being about wording alone. The panel now also reads the shape of your own links, which is what produced every number above. Full detail lives in ARCHITECTURE.md; the short version is that similarity and your link graph disagree often enough to be worth fusing, and roughly a third of the links you make point somewhere similarity structurally cannot look.
Next. Asking the vault questions, and letting other tools use what it knows:
Exploring, for 5.0. Hypotheses with open questions rather than promises:
Ideas that fail their measurement get cut rather than shipped quietly. Bridges, analogy search, a duplicate alarm, a personal similarity metric and a keyword channel were each built, measured, and dropped.
[[ completion: typing [[ ranks existing notes by how well they fit
what you are writing, and offers to create a new note for a strongly relevant
concept that does not have one yet.
~ pill) so it is never empty.
Run "Vault insights (suggested links, orphans, duplicates)" from the command palette to generate a report note for the whole vault:
goa/character tag) from similarity alone, only proposing discriminative tags.It writes/refreshes Vault Insights (Smart Related Notes).md and opens it; every entry
is a clickable wikilink. Nothing is changed in your notes.
Each Markdown note is split into short passages (windows that fit the model's context), covering the whole note, and every passage is turned into a vector by the embedding model. Adjacent passages are then grouped into coherent ideas (~200-500 words, at heading and topic boundaries, with short atomic notes kept whole), so a note is represented at three levels: an overall vector, its idea vectors, and its passage vectors. For the note you're viewing, every other note is ranked by the best cosine similarity of their passages (with its title weighted), blended with how strongly the two notes share a whole idea, so a note related by one coherent idea spanning several paragraphs surfaces, not just one lucky passage match. The closest matches are shown as cards with a similarity percentage.
The model runs through @huggingface/transformers
on the local ONNX runtime, on the CPU via WASM by default, multi-threaded so a
full reindex is quick, and memory-stable. (A WebGPU option exists and is faster,
but its GPU backend can accumulate memory on large vaults, so it's an explicit opt-in.)
The whole engine lives in its own worker, which is shut down after an idle
period (configurable) — so when you're just reading and browsing, the model's
hundreds of MB to several GB are returned to the system instead of sitting resident;
it reloads transparently in a few seconds when next needed. An Indexing speed
setting trades CPU threads against reindex time. The only network traffic ever is
one-time: the model weights from the Hugging Face Hub, and the ONNX runtime
.wasm (version-pinned), which is cached into the plugin's own folder; afterwards
nothing is fetched again and the plugin works offline.
Vectors persist as compact JSON in the plugin's config dir, so the index survives restarts and only changed notes are re-embedded.
For the full picture, see ARCHITECTURE.md: the multi-granularity embeddings, the multi-stage ranking funnel, the measured model A/B, mean-centering, the structural channel that ranks by your link graph, template de-crowding, and where tag-free concept search stands.
paraphrase-multilingual-MiniLM-L12-v2 is a
symmetric sentence-similarity model, the right tool for ranking how alike two
notes are. paraphrase-multilingual-mpnet-base-v2 (Best quality) is stronger but
larger. e5 models are retrieval-oriented and rank note similarity less well.goa).
A note tagged with an activated namespace (matching goa and goa/character) only
relates to, and takes tag suggestions from, other notes in that area, and never
appears in any other note's cards. Notes in no activated area share one pool. A live
ranking knob (no re-index). Use it to keep a self-contained project (a novel, a world)
from bleeding into unrelated notes.Changing the model or compute device transparently rebuilds the index; unrelated changes (sliders, toggles) never trigger a re-embed.
Settings -> Community plugins -> Browse -> "Smart Related Notes" -> Install. That is the whole thing, and it is how almost everyone should install it.
On first launch the model weights download from the Hugging Face Hub with a
progress notice, then cache. This happens once; after that the plugin works
offline. The WASM (CPU) path, the default, uses quantized weights (110 MB); the
optional WebGPU path uses fp32 weights (470 MB for the default model). The model
is downloaded once per backend, then cached. The plugin also fetches the
version-pinned ONNX runtime once, into its own ort/ folder.
If the store has not caught up yet, or you want to track development, add this
repository in BRAT, or download
main.js, manifest.json and styles.css from the
latest release into
.obsidian/plugins/smart-related-notes/ yourself.
An automated review of a release flags four capabilities; each is there on purpose:
~/.cache/smart-related-notes/, never inside the
vault, so sync tools and backups are not dragged through them. Nothing
else outside the vault is read or written; the optional offline setup
additionally reads your Downloads folder, only while its dialog is open.main.js,
which contain a self-test helper for their native binary.Releases carry GitHub artifact attestations, and the review's build
verification reproduces main.js from this repository byte for byte.
A TypeScript project bundled with esbuild (entry src/main.ts → root main.js).
npm install # install dev dependencies
npm run dev # esbuild watch build (inline sourcemap, no minify)
npm run build # gen-ort -> tsc --noEmit -> minified production bundle
npm run lint # eslint (typescript-eslint + eslint-plugin-obsidianmd)
gen-ort.mjs runs before tsc/lint/esbuild: it writes src/ort-version.ts (the
pinned onnxruntime-web version + the CDN base the runtime is downloaded from)
and copies the matching onnxruntime-web .wasm/.mjs assets into ort/ for
local dev builds. Both are build artifacts and are gitignored. Releases ship only
main.js, manifest.json, and styles.css (exactly what Obsidian downloads);
at runtime the plugin caches the pinned ONNX runtime into its ort/ folder on
first use, validated against byte sizes pinned at build time so torn writes or a
plugin update carrying a different runtime build trigger a clean re-download
instead of mixing builds.
The embedding engine (transformers.js + onnxruntime-web) runs inside a dedicated
Web Worker bundled as a second esbuild stage and inlined into main.js (see
esbuild.config.mjs and src/worker/embed-worker.ts); terminating that worker is
what returns the engine's memory to the OS when idle. Environments that expose a
Node-like process would make transformers.js pick the (externalized,
unavailable) onnxruntime-node backend — src/ort-shim.ts (imported first in
the worker entry) flips the relevant process markers during module evaluation so
the web runtime is used and WebGPU/WASM work.
MIT © 2026 Saiki77