Documentation

Every feature

The complete surface: editor, palette, tags, backlinks, tasks, templates, calc.

The hard part of this app is not adding features. It's staying light while doing it. Every note app dies the same death: each feature is individually reasonable, and the sum is Obsidian's settings tree.

The rule that keeps it light

Core is what a majority of users touch weekly and costs under ~10KB. Everything else is a lazy-loaded plugin.

This is why the plugin host (M4) is not a "nice to have" — it's the pressure valve that lets us say yes to Mermaid, KaTeX, and graph views without any of them costing a byte to the person who never opens them.

A second rule, for the "simpler than Obsidian" goal:

Workflow configuration stays in notes. The compact Settings palette is for device presentation choices and direct links into vault-backed settings; deeper feature configuration belongs in a note or a plugin.


Tier 1 — earn their place in core

Ordered by value-per-byte. Sizes are rough.

Status: 1-9, 11 and 12 shipped (2026-08-27). Remaining: 10 (quick capture).

# Feature Why it earns it Cost
1 Daily notesSpace d opens journal/2026-08-25.md, creating from a template The single highest habit-forming feature in this category. It gives a new user a reason to open the app tomorrow. ~40 lines
2 Jump listCtrl-o / Ctrl-i back and forward through visited notes Link-following is the core loop; without history it's a maze. Vim users expect it. The store already has everything needed. ~30 lines
3 Frecency in the file palette — rank by recently/frequently opened, not alphabetically Makes ⌘K feel telepathic. The single cheapest perceived-quality win available. ~25 lines
4 Heading outline@ in the palette jumps to a heading in the current note The palette exists, the markdown tree is already parsed. Nearly free, used constantly in long notes. ~30 lines
5 Task rollup — a palette mode listing every - [ ] in the vault Obsidian's most-installed plugin category. Here it's a filter over the content cache we already keep warm. ~50 lines
6 Search operatorstag:meta, path:notes/, -exclude, "exact phrase" Cheap on top of the existing scan, and it's the difference between "has search" and "search is good". ~40 lines
7 Templatestemplates/*.md, made from any note, applied with / in the editor or Space m / Space ⇧M. Placeholders, tab stops, prompts, property merging, per-folder defaults. See TEMPLATES.md Unlocks daily notes, meeting notes, and every personal workflow, without any of them being a feature we ship. ~50 lines
8 Image paste → attachments — paste a screenshot, get ![[attachments/…png]] Not having this reads as broken. Expected baseline. ~40 lines
9 Frontmatter propertiesvault/frontmatter.ts, with aliases: honoured by the palette and by [[links]] Aliases make a note findable by every name you'd call it. Sets up filtering later without committing to a database UI. ~60 lines
10 Quick capture — a one-line modal that appends to inbox.md and dismisses Catching a thought without leaving what you're doing. Becomes genuinely excellent on desktop with a Tauri global hotkey. ~60 lines
11 Split pane — shipped as full tiling panes + 9 workspaces (src/panes/), ⌃⌥ bindings Read one note while writing another. Went past a single split because the layout tree costs the same as a boolean and gives dwindle tiling, directional focus, and per-workspace layouts for free. shipped
12 Vim mode@replit/codemirror-vim (the @codemirror/vim named here does not exist), lazy-loaded into a compartment, 120KB off the main bundle Given the omarchy audience this is close to mandatory. Lazy-loading means non-vim users pay nothing. 1 import, ~30KB lazy

Items 1-9, 11 and 12 have shipped. Everything except vim mode cost about 5KB gzipped in total — which is the whole argument for this list. Vim mode costs nothing to anyone who leaves it off, which is the argument for the other one.

Only quick capture (10) is left, and C3 in IDEAS.md ("log to today") is the cheaper, more-used version of it.

Panes deliberately keep exactly one live editor — the focused one. Two live CodeMirror views would mean two autosave loops and two dirty flags racing over the same vault; focus-then-type is both the tiling-WM convention and the cheaper invariant.


Tier 2 — plugins, never core

Each is genuinely loved by some users and dead weight for most. This list is the argument for building M4 before M5.

Feature Why it's a plugin
Math rendering KaTeX is ~280KB — larger than the entire current app
Mermaid diagrams ~500KB, and used by a small minority
Graph view Force layout + canvas; visually impressive, rarely load-bearing
Git sync Strong opinions, real setup cost, not everyone's workflow
Kanban / calendar views A different app wearing this app's clothes
Citations / Zotero Deep, narrow, academic
Spaced repetition Deep, narrow, and its users are devoted
Excalidraw / canvas Huge dependency, and not plain text

Where the product outgrew this document (2026-09-01)

Two things below were written as refusals and then shipped as core. Recording the reversal so the admission test in docs/Audit_Adjustments.md §4 has a truthful baseline.

Encrypted sync is core now — not "refuse, ship a git plugin"

ACCOUNTS-AND-SYNC.md is the real design. The reasoning that changed: the target user wants their own files and wants them on two machines without standing up Syncthing or learning git. iCloud/Dropbox don't solve conflict resolution for a folder of prose, and they see the plaintext. Slate's build is end-to-end encrypted (two passwords, wrapped DEK, path HMAC), the server never holds a key, and local-only use is untouched — the vault is still a folder of .md files that works in any editor with sync switched off. It earns core on the same "most users, and it compounds the core loop" test as daily notes: a note you can't get to from your other machine is a note you stop trusting. Still true: no telemetry, no network call the user didn't initiate. A git sync plugin stays welcome for the people who want that instead.

AI is core code, but Tier-2 surface — enforced, not just promised

The implementation is a large subsystem (app/src/ai/), and that's fine. What was wrong was the surface: ~22 always-visible commands, four leader chords, a permanent statusline chip when nothing was configured. As of 2026-09-01 that's gone — every AI command, shortcut, chord, and the statusline segment is when-gated on a provider being picked (Command.when, aiEngaged). "Pick an agent" is the one visible door. So AI is Tier 2 as the user experiences it — absent until requested — while living in core as code. The shape stays the one in IDEAS.md D9: output lands in the note as an editable blockquote, and the statusline says when a request leaves the machine.

The map is core, lazily — not "graph view, never core"

Tier 2 below still says Graph view — force layout + canvas; visually impressive, rarely load-bearing, and UX-ADDITIONS.md refused it outright. Both were arguing about a vault-wide cloud, and both were right about that one. What shipped is a neighbourhood: focused on the open note at one hop by default, typed by connection kind (links, tags, contacts), with the legend doubling as the filter. It answers the question a list cannot — the shape — and Connections keeps answering the one it can.

The cost objection is answered by construction rather than by promise. The builder (vault/graph.ts) is ~250 lines of pure function over indexes the vault already keeps warm; the canvas and the force simulation live behind a dynamic import() (components/MapCanvas.tsx), so a person who never opens the map downloads none of it — the same bargain vim mode, xterm and mathjs already make. That is what the "everything else is a lazy-loaded plugin" rule was protecting; a plugin would have had to re-read the whole vault across postMessage to rebuild an index that already exists.

The plugin-shaped piece is still coming and is genuinely better for having waited: a graph block in the plugin vocabulary, host-rendered like terminal, so a third-party map ships nodes and edges and never names a colour. It is only possible because the host now has a renderer.


Tier 3 — refuse, at least through v1

Feature Why not
Real-time collaboration Requires CRDTs and a server. It changes the data model from "files you own" to "a database we host" — it contradicts the product.
Notion-style databases Fights plain text. The moment a view can't round-trip to markdown, the file-ownership promise is broken.
WYSIWYG that isn't markdown underneath Same reason. Live preview gives the feel without the lie.
Mobile-responsive layout This app's entire thesis is the keyboard. A phone has no keyboard. Mobile deserves a different design, not a media query — and not in v1.

Foundation debt paid (2026-08-25)

Bugs found by testing, not by reading:

Bug Root cause
Editor rendered blank with no vault Grid declared 2 columns; only 1 child rendered, so the surface got the 0px track
New note put the caret before the # Note switch hard-coded anchor: 0
⌘⇧. blockquote silently did nothing Shift rewrites e.key (.>); bindings now resolve punctuation via e.code
Numbered lists emitted 1. on every line Line-prefix toggle had no counter
A tag you just typed never reached the sidebar Incremental reindex updated links but not the tag map
#123 and #2026 counted as tags Tag pattern allowed all-numeric names
⌃O split the line instead of navigating back CodeMirror's macOS emacs keymap won; the app keymap now runs in capture phase
A pasted image vanished instead of rendering The embed's replace decoration was nested inside a second one from its child marks; two overlapping replacements render as an empty span. Iteration now stops at the embed.

A regression suite landed with this batch: 134 tests, ~1s, covering every pure module above. Six of the seven bugs listed here lived in code that is now under test.

Shipped since (2026-08-27)

Work Where
External-change detection and conflict resolution vault/vaultStore.ts — SYNC.md §0 is closed
[] → checkbox, Enter continues, Backspace removes editor/tasks.ts
Task board writes through to the open buffer vault/vaultStore.ts applyExternalWrite
Timer sound + fact panel plugins/sounds.ts, builtin/timer.plugin.js
[[Note#Heading|Alias]] honoured end to end B1, B2, B3 in IDEAS.md
Configuration is a note D1 — vault/config.ts, slate.md
The theme travels with the vault D2, free once D1 existed
Local history D4 — vault/history.ts, ⌃⌥Z
Full screen, as one dial with zen store/useStore.ts viewMode, the top bar chip
Compact Settings palette Device-local editor type, size, spacing, width and motion; vault Vim mode remains in slate.md
Generic Markdown folder import Read-only source copy into imports/, deterministic names and a linked report
A plain question in the AI console ai/catalog.ts prompt, first row
One press back to the AI action list ai/useConsole.ts reset, ⇧esc and the
Accounts — sign in/up/out, no vendor UI account/, AccountDialog.tsx, supabase/schema.sql
Selective sync policy — nine categories, folder exclusions sync/selection.ts, the sync palette mode
End-to-end crypto — two passwords, wrapped DEK, path HMAC, recovery code sync/crypto.ts
Sync engine — cursor pull, CAS push, blob upload, conflict detection sync/engine.ts, sync/remote.ts, sync/state.ts
Sync wired up — vault password, recovery code, statusline, ⌘⌥S sync/useSync.ts, VaultUnlockDialog.tsx
Automatic sync — realtime poke, local debounce, focus sync/auto.ts, schema-003-realtime.sql
Three-way merge and conflict files sync/merge.ts, the conflicts palette mode
Synced version history, with restore the versions palette mode
The account, at the foot of the sidebar and on the welcome screen SidebarAccount.tsx
First sync into a populated folder asks before writing survey(), FirstSyncDialog.tsx

The highest-leverage work isn't a feature

The stated goal is "simpler to pick up than Obsidian." Obsidian's real failure isn't its feature count — it's that a new user opens it to an empty vault, a ribbon of fourteen icons, and no idea what to do.

Ship a first run that teaches itself. On first open, offer to create a three-note starter vault: one note that links to a second, a third tagged #example, and a visible hint to press ⌘K. Sixty seconds to "I understand this app," with no documentation and no settings screen.

That is worth more than any five features on this page.