DEV Community

Cover image for I built a markdown notes app where every note is a plain file, and search runs on the device
Lavneet Sharma
Lavneet Sharma

Posted on AI-assisted

I built a markdown notes app where every note is a plain file, and search runs on the device

I wanted Bear's editor on every device I use, with notes that stay mine as plain files. So I built VB Notes: a free, open-source (MIT) markdown notes app for iPhone, Android, Mac, Windows and Linux.

VB Notes on the desktop: nested tags in the sidebar, the notes list, and a note with checklists and a Mermaid diagram

Every note is a file

You pick a folder (iCloud Drive, a Syncthing folder, or just one on the device) and every note is a .md file in it. There's no database of the app's own to export from and no account. Obsidian, Vim, grep, git or a script can work on the same notes, and anything that writes a markdown file into the folder shows up as a note.

Tags live in the text, nested like #work/clients, so they survive any app. The editor formats as you type, the way Bear does: headings, checklists, tables, code coloured by language, Mermaid diagrams, pictures and voice notes, all saved as ordinary markdown.

Search by meaning, on the device

Search understands what you mean, not only the words you typed. "What does my flatmate owe" finds a note called "Rent split with Arjun", though they share no words.

VB Notes on iPhone: searching "what does my flatmate owe" finds the note "Rent split with Arjun", marked "by meaning"

The model runs on the phone or the computer, so neither your notes nor your searches leave it. That was the part I most wanted to get right.

How it's built

The phone app is Expo and React Native. The editor is Tiptap 3 running in a WebView (through 10tap), with my own extensions for tag pills, [[wiki links]], code blocks and media. A WebView takes a moment to start, so while it does, the app draws the note natively, matched to the editor pixel for pixel, and the note doesn't jump when the editor takes over.

The notes list, tags and keyword search come from a SQLite index with FTS5, rebuilt from the files whenever it's missing. The files stay the source of truth.

The desktop app is Tauri 2, not Electron. Rust scans the folder, watches it for changes and keeps the same SQLite index; the page runs the same editor extensions as the phone. The installers are 14 MB on Mac, 5 MB on Windows and 7 MB for the Linux .deb.

Search by meaning: notes are split into chunks with the title on each, and embedded with LFM2.5-Embedding-350M. On the phone it runs through react-native-executorch and the vectors are stored as int8 in SQLite; on the desktop the same model runs as a GGUF file through llama.cpp, on Metal on Apple Silicon. Meaning matches are merged with keyword matches using reciprocal rank fusion, so an exact word still wins when you type one.

The desktop quick finder: typing "fitness" offers to create a note and finds "Half marathon plan" by meaning

On the desktop, ⌘O / Ctrl+O opens a quick finder: the first row always creates a note with what you typed, and the rest are matches by words and by meaning.

There's also an optional AI chat that uses your own API key (OpenRouter, OpenAI, Anthropic, Gemini, Ollama and others), off until you turn it on.

What it doesn't do yet

No iPad version, no web app, and no sharing or real-time collaboration. Sync is whatever syncs your folder: iCloud Drive works today, Google Drive isn't built yet. It's young and made by one person, so there are rough edges.

Try it

I'd like to hear what's missing for you, or what would make you move your notes over.

Top comments (0)