Terminal notes: Markdown files with folders, #tags, [[links]] and a mouse-first TUI.
Fast, minimal note-taking that never leaves your terminal. Plain .md on disk, live Markdown highlighting while you type, emacs or vim keys, and a headless JSON CLI so scripts and AI agents work the same vault.
Interface preview
1 tnotes roadmap 2 Weekly plan × # Weekly plan #work #planning - [x] Review pull requests - [x] Write release notes - [ ] Ship tnotes 1.1 #tnotes — see [[tnotes roadmap]] - [ ] Book flights for **Berlin** #travel - [ ] Prep [[Meeting notes]] > Keep the list short.
Left: folders, tags and the note list. Right: tabs and the editor. Everything is clickable; everything has a key.
Why tnotes
01 Files, not a database
One .md per note, folders are directories, tags live in the text. Atomic saves, conflict copies instead of silent overwrites, live reload. Sync with anything.
02 A real editor
Live highlighting, list continuation, checkbox toggling, word wrap, link and tag completion, backlinks. Emacs or vim keys. Mouse works everywhere.
03 Scriptable by design
tnotes ls --json gives every note with tags, links, backlinks and timestamps. Agents and cron jobs write; your open TUI updates live.
# Features
Most of what tnotes does is on screen at once. The numbers point at it; the manual below lists the rest.
1 tnotes roadmap 2 Weekly plan × # Weekly plan #work #planning - [x] Review pull requests - [x] Write release notes - [ ] Ship tnotes 1.1 #tnotes — see [[tnotes roadmap]] - [ ] Book flights for **Berlin** #travel - [ ] Prep [[Meeting notes]] > Keep the list short.
- 1Folders are directoriesEvery root and subfolder in the tree is a real directory on disk.
- 2#tags, parsed from the textNested ones like
#work/projecttoo. Click one to filter. - 3Fuzzy search/ searches titles and bodies (nucleo), combined with tag and folder filters.
- 4Tabs with a preview tabSelecting a note previews it; typing or enter pins it. 1–9 jumps.
- 5Tags live in the noteNo frontmatter, no sidecar file: the tag line is the tag.
- 6Lists that behaveenter continues, an empty item ends, tab nests, alt+x or a click toggles the box.
- 7[[Links]] with completionPopup after
[[, alt+enter follows, a missing target is created, links are rewritten on rename. - 8Live Markdown highlightingHeadings, emphasis, code, quotes, links and tags styled as you type; colour or mono.
- 9Autosave, atomic, never lostWritten after 500 ms idle to a temp file then renamed; a conflict copy instead of an overwrite; a failed save keeps the text under the state dir.
- 10BacklinksCount in the status bar, overlay on alt+enter, and a
backlinksfield in the CLI's JSON. - 11Emacs or vim keysedtui underneath. Switch on the settings page (F2).
$ man tnotes
FILES
- .md on disk
- One file per note, named after its title. Atomic saves,
name (conflict <time>).mdinstead of a silent overwrite, live reload when a file changes outside the app. - folders
- Real directories. Every root has its own
.Trash/mirroring the layout, so u undoes and r restores. - #tags
- Parsed from the text, nested
#work/projectincluded. Nothing else is written next to your notes. - sync
- Any file sync: git, Syncthing, iCloud, Dropbox. Syncer conflict files are listed as ordinary notes.
EDITOR
- [[links]]
- Completion popup after
[[, alt+enter or ctrl+click to follow, backlinks overlay, rewritten when a title changes. - - [ ] lists
- enter continues, empty item ends, tab / shift+tab nest, alt+x toggles a checkbox.
- highlighting
- Headings, lists, checkboxes, code, links, emphasis, quotes, tags as you type. Colour or monochrome; the theme follows your terminal palette.
- emacs | vim
- edtui keys. Vim has normal and insert modes,
.repeat and/search. - wrap, width
- Word wrap at a configurable column, left or centred, drawn or terminal cursor.
NAVIGATION
- tabs
- One preview tab; editing pins it. 1–9 jumps, alt+. / alt+, cycle, ctrl+w closes.
- / search
- Fuzzy over titles and bodies, combined with the tag and folder filter. s changes the sort.
- mouse
- Click selects, double-click pins, right-click opens a context menu, wheel scrolls, drag selects text and copies on release.
- session
- Open tabs, filter, sort, focus and folded tree sections come back on the next launch.
- narrow
- A single-panel layout on small terminals; ctrl+b toggles the sidebar.
- F2
- An in-app settings page that writes
config.tomlfor you.
CLI
- tnotes ls --json
- Every note with id, path, title, folder, tags, links, backlinks, created, modified, preview.
--tag,--folder,--limit. - search · cat
- Fuzzy search, best first;
catprints a note,--jsonadds the text. - new · append · write
- Create, add a line, replace the text; all take
--stdin. A changed title renames the file and updates links. - trash · restore
- To the root's
.Trash/and back. Nothing is deleted outright. - live
- A running TUI picks CLI changes up; a tab with unsaved edits is never overwritten. No daemon, no API: files and JSON, which is all an agent needs.
# How it feels
Capture
ctrl+t, type a title, keep typing. Autosave after 500 ms of idle.
# Groceries#home- [ ] milk- [ ] coffee⏎- [ ] ▌Link
Type [[, pick from the popup, alt+enter to jump. Rename a note and every link follows.
- [ ] Prep [[Meet▌ ┌────────────────┐ │ Meeting notes │ │ Meetup ideas │ └────────────────┘Automate
Pipe text in from anywhere. The open TUI shows it the moment the file lands.
$ echo "- [ ] call Ann" \ | tnotes append weekly-plan --stdin$ tnotes search "berlin" --json \ | jq '.[0].path'"vault/weekly-plan.md"# Built for AI agents
The CLI is the agent interface: no daemon, no API keys, no plugin, just files and JSON. Point an agent at your vault and let it read, search and write notes while you keep the TUI open. Edits show up live in both directions; a note with unsaved edits in the TUI is never overwritten.
links and backlinks in the JSON let an agent walk the note graph. Ids (root/sub/stem) are the same in every command.
$ tnotes ls --json | jq '.[0]'{ "id": "vault/weekly-plan", "path": "/home/me/notes/vault/weekly-plan.md", "title": "Weekly plan", "folder": "vault", "tags": ["work", "planning"], "links": ["tnotes roadmap", "Meeting notes"], "backlinks": ["tnotes roadmap"], "created": "2026-09-21T09:12:04Z", "modified": "2026-09-22T08:40:11Z", "preview": "#work #planning - [x] Review pull requests …"}# Install
One binary, no account, no daemon. v1.3.0 · macOS and Linux · MIT. Four steps, about a minute.
Get the binary
▸ Static binary, any distro
recommended$ V=1.3.0; T=x86_64-unknown-linux-musl$ curl -sL https://github.com/0x1ocean/tnotes/releases/download/v$V/tnotes-$V-$T.tar.gz | tar xz$ install tnotes-$V-$T/tnotes ~/.local/bin/musl build: no glibc version to match, works on Debian, Arch, Alpine, NixOS, a fresh container. On aarch64 (Raspberry Pi, Graviton): T=aarch64-unknown-linux-gnu.
upgrade: re-run with the new version number
▸ other ways on Linux (Homebrew on Linux, cargo)
Homebrew on Linux
$ brew install 0x1ocean/tnotes/tnotesx86_64 and aarch64. Prebuilt, no Rust needed.
upgrade: brew upgrade tnotes
cargo
$ cargo install tnotesBuilds from crates.io. Rust ≥ 1.98.
upgrade: cargo install tnotes --force
No AUR, deb or rpm packages yet; the static tarball is the portable answer until then.
▸ Homebrew
recommended$ brew install 0x1ocean/tnotes/tnotesApple Silicon and Intel. Prebuilt bottle, no Rust needed.
upgrade: brew upgrade tnotes
▸ other ways on macOS (Prebuilt tarball, cargo)
Prebuilt tarball, Apple Silicon
$ V=1.3.0; T=aarch64-apple-darwin$ curl -sL https://github.com/0x1ocean/tnotes/releases/download/v$V/tnotes-$V-$T.tar.gz | tar xz$ install tnotes-$V-$T/tnotes ~/.local/bin/Intel: T=x86_64-apple-darwin. A .sha256 sits next to every tarball.
upgrade: re-run with the new version number
cargo
$ cargo install tnotesBuilds from crates.io. Rust ≥ 1.98.
upgrade: cargo install tnotes --force
Binaries are not signed. Homebrew and curl downloads run as-is; a tarball saved through the browser is quarantined by Gatekeeper: xattr -d com.apple.quarantine tnotes clears it.
▸ cargo, from crates.io
recommended$ cargo install tnotesAny platform with Rust ≥ 1.98. Windows is untested.
upgrade: cargo install tnotes --force
▸ other ways on From source (Current main branch)
Current main branch
$ cargo install --git https://github.com/0x1ocean/tnotesIncludes the vendored word-wrap fork of edtui. May be ahead of the changelog.
upgrade: re-run
Check it runs
$ tnotes --versiontnotes 1.3.0If the shell says
command not found,~/.local/binis not on yourPATHyet; open a new shell or add it.Open your notes
$ tnotes ~/notesAny folder of
.mdfiles works, including an existing Obsidian vault. The folder is saved as a root and opened next time by plaintnotes. Without an argument, the first launch asks where notes live (default~/Documents/notes).--diropens a folder for one session only.Learn five keys
- ctrl+t new note
- / search
- [[ link a note
- alt+enter follow the link
- ? everything else
Then: getting started · all keys · config · use with AI agents.
# Sync and encryption are the file system's job
Put a root inside Syncthing, iCloud Drive, Dropbox or a git repo. Changes from another device show up live; saves are atomic so a syncer never sees a half-written note; concurrent edits become a conflict copy, never a lost one.
Encrypt the folder, not the notes: FileVault, an encrypted .dmg, gocryptfs or fscrypt. Point roots at the mounted path and everything keeps working.
~/.config/tnotes/config.tomlroots = ["~/Sync/notes", "~/work/wiki"][editor]keys = "vim"autosave_ms = 500width = 72[theme]accent = "cyan"tag = "green"# Read more
- Comparetnotes vs Obsidian, nb, jrnl, Logseq, vimwiki, org-mode and more, with recipes for using both.
- Use casesSetups for vim users, Obsidian users, sysadmins over SSH, dotfiles people and AI agents.
- GuidesTerminal note-taking, wikilinks, plain-text sync and encryption, notes memory for Claude Code.
- GlossaryWikilink, backlink, TUI, Zettelkasten, vault, frontmatter, and how each works here.
# FAQ
- ? Where are my notes stored?
- As plain .md files in the folders you choose (default ~/Documents/notes). One file per note, named after its title. Nothing else is written next to them, so the folder is safe to sync with git, Syncthing, iCloud Drive or Dropbox.
- ? Does tnotes work with Obsidian or other Markdown apps?
- Yes. Notes are ordinary Markdown with [[wikilinks]] and #tags in the text, so the same folder can be opened by any Markdown editor. tnotes reloads live when a file changes outside the app.
- ? Can I use vim keys?
- Yes. Set editor.keys = "vim" in the config or in the in-app settings page (F2). The default is emacs-style keys.
- ? How do AI agents use tnotes?
- Through the headless CLI: tnotes ls, search, cat, new, append, write, trash and restore, all with --json. No daemon, no API, just files. A running TUI picks the changes up live.
- ? Is it free?
- Yes. tnotes is open source under the MIT license.
- ? Does it run on Windows?
- Untested. Prebuilt binaries ship for macOS and Linux; cargo install may work on Windows but is not supported.