English · 简体中文
A local-first outliner for VS Code, running on plain Markdown files.

Your notes are just a standard .md indented list — Obsidian and Logseq read them directly, and Git diffs stay readable. No proprietary format, no account, no cloud. Uninstall the extension and your files are still plain Markdown.
Features
- Unlimited nesting —
Enterto split,Tab/Shift+Tabto re-level,Backspaceto merge - Fold / unfold — folding state lives in VS Code and is never written to your files
- Zoom in — focus any subtree, with breadcrumb navigation
- Task checkboxes — serialized as standard
- [x] - Node notes —
Shift+Enteropens a second line, stored as an indented continuation - Move and drag —
Alt+↑/↓moves a whole subtree; drag with the mouse to reorder across levels - Live search filter — keeps the ancestor chain, sees through folded nodes
- Inline Markdown —
`code`,**bold**,==highlight==and links render as you read; click in and you get the raw Markdown back. Paste a URL over selected text to turn it into a link - Code blocks — syntax highlighting for 12 languages, switchable per block, with a copy button
- Images —
![[pic.png]]andrender inline; paste a screenshot and it lands in the note'sassets/folder - Sidebar — top-level navigation and starred nodes, collapsible
- Multi-select — shift-click or
Shift+↑/↓to act on several nodes at once - Mirror references — the same node in several places, edited in sync, using Obsidian's native
^id/![[#^id]]block-embed syntax - Full IME support for Chinese, Japanese and Korean input
- Undo / redo delegated to VS Code's native undo stack — no second history to fight with
Keyboard shortcuts
| Key | Action |
|---|---|
Enter |
Split the node at the caret (at the end of an expanded parent: create its first child) |
Shift+Enter |
Focus / create the node note; insert a newline inside a note |
Tab / Shift+Tab |
Indent / outdent |
Backspace (at line start) |
Merge with the previous node |
Alt+↑ / Alt+↓ |
Move the node up / down, children included |
Cmd/Ctrl+Enter |
Toggle done |
Alt+→ / Alt+← |
Zoom into the current node / zoom out one level |
Cmd/Ctrl+. |
Fold / unfold the current node |
↑ / ↓ |
Move to the adjacent node when on the first / last line |
Cmd/Ctrl+Z / Cmd/Ctrl+Shift+Z |
Undo / redo (VS Code native) |
Cmd/Ctrl+F |
Focus the outline search box |
Shift+↑ / Shift+↓ |
Extend the node selection |
Ctrl+B / Ctrl+H |
Bold / highlight the selected text (Ctrl+Alt+B / Ctrl+Alt+H off macOS) |
Ctrl+O |
Hide / show completed nodes (Ctrl+Alt+O off macOS) |
? |
Show all shortcuts |
Esc |
Clear the search / cancel a drag |
Use Cmd on macOS, Ctrl on Windows and Linux.
The formatting and hide-completed keys deliberately avoid Cmd+B / Cmd+O: webview keystrokes are handed to the workbench for keybinding resolution, so VS Code's own bindings (toggle sidebar, open file) win no matter what the webview does. The floating toolbar that appears over selected text is the primary entry point for formatting.
Usage
-
*.outline.mdopens in OutlineNode by default. -
For any other
*.md: click⋯in the editor title bar → Reopen Editor With… → Outline, or runOutlineNode: Open as Outlinefrom the command palette. -
To make every
.mdunder a given folder (sayoutlines/in an Obsidian vault) open as an outline, use VS Code's nativeworkbench.editorAssociations:{ "workbench.editorAssociations": { "**/outlines/**/*.md": "outlineNode.outline" } }Remove the entry to go back to the text editor. Your files are untouched either way.
Interop with Obsidian / Logseq
What lands on disk is an ordinary Markdown indented list:
- This week ^k3f9a2
- Write the weekly report
- Collect last week's numbers
- [x] File the expense
A note lives on an indented continuation line
- Reference the item above: ![[#^k3f9a2]]
- Obsidian —
^k3f9a2is a block id and![[#^k3f9a2]]is a block embed, so Obsidian renders it as a real embed. Same meaning on both sides. - Logseq and other outliners — an indented list is the lingua franca; they read it as-is.
- Git — one edit produces a diff on the lines you edited, not a reflow of the whole file.
Settings
| Setting | Default | Description |
|---|---|---|
outlineNode.defaultIndent |
2-space |
Indent unit for new files, or when it can't be detected (2-space / 4-space / tab) |
outlineNode.rememberFolding |
true |
Remember folding state across sessions |
outlineNode.defaultFold |
none |
Folding applied when a file opens (none / firstLevel) |
outlineNode.cleanupUnusedImagesOnSave |
true |
Move unreferenced pasted-* images generated by OutlineNode to the trash after saving |
For existing files the indent unit is detected from the content and is never overridden by this setting.
Design principles
- The file is the single source of truth. The
TextDocumentis the model, so undo, the dirty indicator, saving and hot restore all come from VS Code itself. - Minimal diffs. An edit rewrites only the lines it touches — no opportunistic reformatting of the rest of the file, which stays byte-for-byte identical.
- UI state never hits disk. Folding, zoom and search live in VS Code. Your
.mdstays clean.
Contributing
See AGENTS.md and docs/ for the full technical specification.
License
MIT
Bundled third-party code: Prism (MIT) — syntax highlighting for code blocks, bundled into the webview because the extension's CSP forbids loading anything from a CDN.