---
title: "tnotes — terminal Markdown notes with #tags, [[links]] and a CLI"
description: "Terminal notes: Markdown files with folders, #tags, [[links]], a mouse-first TUI and a JSON CLI for scripts and agents"
canonical: https://tnotes.app/
---

# 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.

[install](#install)[read the docs](/docs)[github ↗](https://github.com/0x1ocean/tnotes)v1.3.0 · MIT · macOS & Linux

## Interface preview

_tnotes terminal interface: a folder and tag tree, a note list, tabs, and the Weekly plan note open in the Markdown editor_

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.

_tnotes terminal interface: a folder and tag tree, a note list, tabs, and the Weekly plan note open in the Markdown editor_

1.  1Folders are directoriesEvery root and subfolder in the tree is a real directory on disk.
2.  2#tags, parsed from the textNested ones like `#work/project` too. Click one to filter.
3.  3Fuzzy search/ searches titles and bodies (nucleo), combined with tag and folder filters.
4.  4Tabs with a preview tabSelecting a note previews it; typing or enter pins it. 1–9 jumps.
5.  5Tags live in the noteNo frontmatter, no sidecar file: the tag line is the tag.
6.  6Lists that behaveenter continues, an empty item ends, tab nests, alt+x or a click toggles the box.
7.  7\[\[Links\]\] with completionPopup after `[[`, alt+enter follows, a missing target is created, links are rewritten on rename.
8.  8Live Markdown highlightingHeadings, emphasis, code, quotes, links and tags styled as you type; colour or mono.
9.  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.
10.  10BacklinksCount in the status bar, overlay on alt+enter, and a `backlinks` field in the CLI's JSON.
11.  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>).md` instead 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/project` included. 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.toml` for 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; `cat` prints a note, `--json` adds 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.

[agent recipes →](/agents)

```
$ 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.

1.  ### Get the binary
    
    Operating systemLinuxmacOSFrom source
    
    ### ▸ 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/tnotes
    ```
    
    x86\_64 and aarch64. Prebuilt, no Rust needed.
    
    upgrade: brew upgrade tnotes
    
    #### cargo
    
    ```
    $ cargo install tnotes
    ```
    
    Builds 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/tnotes
    ```
    
    Apple 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 tnotes
    ```
    
    Builds 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 tnotes
    ```
    
    Any 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/tnotes
    ```
    
    Includes the vendored word-wrap fork of edtui. May be ahead of the changelog.
    
    upgrade: re-run
    
     
    
2.  ### Check it runs
    
    ```
    $ tnotes --versiontnotes 1.3.0
    ```
    
    If the shell says `command not found`, `~/.local/bin` is not on your `PATH` yet; open a new shell or add it.
    
3.  ### Open your notes
    
    ```
    $ tnotes ~/notes
    ```
    
    Any folder of `.md` files works, including an existing Obsidian vault. The folder is saved as a root and opened next time by plain `tnotes`. Without an argument, the first launch asks where notes live (default `~/Documents/notes`). `--dir` opens a folder for one session only.
    
4.  ### Learn five keys
    
    -   ctrl+t new note
    -   / search
    -   \[\[ link a note
    -   alt+enter follow the link
    -   ? everything else
    
    Then: [getting started](/docs/getting-started) · [all keys](/docs/keys) · [config](/docs/config) · [use with AI agents](/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.

[sync recipes →](/docs/sync)

```
~/.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.](/compare)
-   [Use casesSetups for vim users, Obsidian users, sysadmins over SSH, dotfiles people and AI agents.](/for)
-   [GuidesTerminal note-taking, wikilinks, plain-text sync and encryption, notes memory for Claude Code.](/guides)
-   [GlossaryWikilink, backlink, TUI, Zettelkasten, vault, frontmatter, and how each works here.](/glossary)

## \# 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.
