a Obsidian
alternative,
honestly.
A second brain for you, forever. Knowledge base that works on top of a local folder of plain text files.
what Obsidian got right.
We're not here to bash. Obsidian earned its users by nailing things outl stands on the shoulders of.
- ✓ Plain markdown on disk, no metadata pollution. Total interop with any markdown tool.
- ✓ Massive plugin ecosystem — over a thousand community plugins for almost anything.
- ✓ Strong [[wiki-links]] and a polished graph view.
- ✓ Free for personal use, with a mature mobile app.
where it breaks for an outliner power-user.
It's a prose editor, not an outliner.
Bullets are just markdown bullets. There's no block-level addressability without plugins, no first-class slash command for blocks, no real outliner mode. Power users install the Outliner plugin, but it's a bolt-on — fold-state, drag-handles and keyboard chords feel grafted.
Built-in sync is a paid black box.
Obsidian's built-in sync is a proprietary cloud subscription. The merge algorithm is undocumented — they call it CRDT-flavored, but you can't audit it and you can't run it on your own hardware. You can self-host with git or Syncthing instead, but those don't handle outline conflicts well. outl ships peer-to-peer sync over iroh by default — device-to-device, end-to-end encrypted, no third-party server, no paid tier — and the tree-CRDT is open-source and auditable.
Closed source.
Free for personal use, but the source is private. You can't read, audit, fork or self-host. If the company changes direction, you're carrying years of notes in a format only their binary fully understands.
Electron. Heavy.
Desktop is Electron. Cold-start is multiple seconds. Memory is generous. For an app that's mostly editing text, the runtime cost is hard to justify.
you want to move 80 bullets from page A to page B.
In a real outliner this is select-and-move. In Obsidian default it's cut, paste, fix the indent, hope nothing referenced those blocks. The Outliner plugin helps a bit with chords, but block references break because Obsidian doesn't track blocks as nodes — it tracks them as ^block-id text anchors in markdown. Move the anchor and any [[page#^id]] link silently breaks.
outl is built as an outliner from line one. Blocks are nodes in a tree. Moves preserve references because IDs are stable in the sidecar — the markdown you see is just the rendering.
Obsidian vs outl
| feature | Obsidian | outl |
|---|---|---|
| open source | ✕ | MIT |
| ships as a native binary | ✕ electron | ✓ rust |
| clean markdown (no UUIDs) | ✓ | ✓ |
| tree-CRDT sync (provably correct) | ✕ | ✓ tree-CRDT + iroh P2P transport |
| P2P sync, no third-party server | ✕ paid cloud | ✓ device-to-device, E2E |
| code blocks that execute (5 langs) | via plugin | ✓ python, lisp, js, lua, rust |
| TUI / terminal editor | ✕ | ✓ vim keys + slash commands |
coming from Obsidian?
one command.
Your Obsidian vault is already plain markdown. Just
outl init
on the vault directory — outl reads your .md files as-is. Backlinks
and [[wiki-links]] resolve automatically. Block references via the
outliner-plugin syntax can be reconciled with a follow-up
outl doctor
run.
And one thing Obsidian doesn't do: outl ships an MCP server so Claude, Cursor and ChatGPT use the same notes as a local-first second brain — no copy-paste, no upload.