← Back to JotMD

README.md / complete reference

Documentation

Install JotMD, learn the keyboard-first terminal workflow, configure your vault, automate safe note updates, and give supported coding agents durable Markdown memory.

Requirements

The Homebrew package is the shortest path on macOS or Linux. Building from source requires Go 1.26 or newer and just.

JotMD opens notes in the editor chosen by --editor, then $JOTMD_EDITOR, configuration, $EDITOR, and finally vi.

Installation

Homebrew

brew install gonfff/tap/jotmd

Build from source

git clone https://github.com/gonfff/jotmd.git
cd jotmd
just install

just install writes the binary to ~/.local/bin/jotmd.

Quick start

Run JotMD once. On first launch it asks where your notes live, creates the directory if needed, and stores the choice in the JotMD configuration directory.

jotmd

To skip the prompt, create a vault and pass it explicitly:

mkdir -p ~/vault
jotmd --notes-dir ~/vault

Layout & focus

The main screen keeps a directory tree beside a wrapping Markdown preview. Select a Markdown file to render it; expand directories in place and press Tab to move focus between the tree, table of contents, and preview.

The bottom status line shows the current note and context-sensitive help. Press ? to see all effective bindings or Shift+P to open the command palette.

Working with notes

JotMD works directly with directories and .md files. There is no database or import format, so Git, sync tools, scripts, and other editors can use the same vault.

  • Create notes and directories with n and N.
  • Edit the selected note with e.
  • Rename, copy, move, trash, restore, or permanently delete items through the command palette.
  • Reload notes, configuration, and key bindings without restarting the TUI.

Permanent deletion cannot be undone. Prefer the trash action unless the file must be removed immediately.

Key bindings

ContextKeyActionConfig key
Treek / Move uptree.up
Treej / Move downtree.down
TreeHomeJump to first itemtree.first
TreeEndJump to last itemtree.last
Treeh / Collapse directorytree.collapse
Treel / Expand directorytree.expand
TreeBackspaceGo to parent directorytree.parent
TreeEnter / SpaceOpen note or toggle directorytree.open
NoteseEdit selected notenote.edit
NotesnCreate notenote.new
NotesNCreate directorydirectory.new
NotesrRename selected itemnote.rename
NotescCopy selected itemnote.copy
NotesmMove selected itemnote.move
NotesdMove selected item to trashnote.trash
NotesDPermanently delete selected itemnote.delete
ApplicationTabCycle focusapp.focus
ApplicationRReload notes, configuration, and key bindingsapp.reload
Application?Open helpapp.help
ApplicationtOpen theme selectortheme.select
Application/Open searchsearch.open
ApplicationShift+POpen command paletteapp.palette
PreviewvToggle rendered and raw Markdownpreview.raw
PreviewwToggle line wrappingpreview.wrap
PreviewsCycle render stylepreview.style
ApplicationaShow or hide agent memoryview.agent_memory
ApplicationqQuitapp.quit
HelpEscClose helphelp.close
Theme selector / Ctrl+PPrevious themetheme.up
Theme selector / Ctrl+NNext themetheme.down
Theme selectorEnterApply themetheme.apply
Theme selectorEscClose without applyingtheme.close

Bindings are configurable in ~/.config/jotmd/keybindings.toml. Each entry replaces the defaults for that action. Print the effective bindings with:

jotmd --dump-keys

Configuration

CLI flags override environment variables, which override config.toml and built-in defaults. Configuration lives under ~/.config/jotmd/, or $XDG_CONFIG_HOME/jotmd/ when that variable is set.

config.tomlCLI flagEnvironmentDefaultWhat it does
notes_dir--notes-dir PATHJOTMD_NOTES_DIR~/vaultDirectory containing the Markdown vault.
editor--editor COMMANDJOTMD_EDITOR, EDITOR (fallback)viCommand used to edit notes.
theme--theme NAMEJOTMD_THEMEjotmdBundled or custom theme name.
theme_colors--theme-colors COLORSJOTMD_THEME_COLORSOverrides individual semantic colors in the active theme.
tree_width--tree-width PERCENTJOTMD_TREE_WIDTH20Tree width percentage from 1 to 100; the rendered pane is clamped to 24–48 columns.
no_color--no-colorJOTMD_NO_COLOR, NO_COLORfalseDisables color output. Any non-empty NO_COLOR also enables it.
show_hidden--show-hiddenJOTMD_SHOW_HIDDENfalseIncludes hidden files and directories.
show_agent_memory--show-agent-memoryJOTMD_SHOW_AGENT_MEMORYfalseShows the reserved agent-memory tree at startup.
ignore--ignore LISTJOTMD_IGNORE[".obsidian", ".git"]Names excluded from the vault tree. CLI and environment values use the OS path-list separator.
sort--sort ORDERJOTMD_SORTnameSort order. Currently only name sorting is supported.
directories_first--directories-firstJOTMD_DIRECTORIES_FIRSTtrueKeeps directories before notes; currently must remain enabled.
status_bar--status-barJOTMD_STATUS_BARtrueShows the bottom status bar.
watch--watchJOTMD_WATCHtrueReloads the vault when files change on disk.
preview.wrap--preview-wrapJOTMD_PREVIEW_WRAPtrueWraps long lines in the preview.
preview.render_style--preview-render-style STYLEJOTMD_PREVIEW_RENDER_STYLEquietMarkdown style: quiet, surface, or structural.
preview.max_bytes--preview-max-bytes BYTESJOTMD_PREVIEW_MAX_BYTES2097152Largest note rendered in preview, up to 67108864 bytes.

Boolean environment values accept forms such as true/false and 1/0; boolean CLI flags also accept explicit values such as --watch=false. Theme color overrides use a TOML inline table such as { accent = "#77AD91" }. Generate templates, inspect the effective result, or validate a file with:

jotmd --init-config
jotmd --dump-config
jotmd config check
jotmd config check /path/to/config.toml

Themes

JotMD ships with 11 themes. Press t in the TUI to select one, or set theme in config.toml.

Use a bundled theme

jotmd --list-themes
jotmd --theme catppuccin-mocha

Create a custom theme

Export the bundled themes, copy one, and edit it. Existing files are never overwritten by --init-themes. The filename becomes the theme name used by --theme.

jotmd --init-themes
cp ~/.config/jotmd/themes/jotmd.toml \
  ~/.config/jotmd/themes/my-theme.toml

If XDG_CONFIG_HOME is set, use $XDG_CONFIG_HOME/jotmd/themes/ instead. A complete theme defines its Markdown syntax style and every semantic palette color:

name = "my-theme"
syntax_style = "rose-pine"

[palette]
foreground = "#E9E2D5"
muted = "#6E6E6B"
border = "#45504A"
border_focus = "#77AD91"
selection_background = "#77AD91"
selection_foreground = "#101512"
accent = "#77AD91"
directory = "#E1B866"
heading = "#E1B866"
link = "#7FA8B8"
code = "#D88762"
status = "#77AD91"

background is optional. Colors use hexadecimal notation. Unknown fields, missing required colors, and unsupported syntax styles are rejected.

jotmd --dump-theme my-theme
jotmd --theme my-theme

Override a few colors

For a small adjustment, keep the base theme and override only selected semantic colors in config.toml:

theme = "jotmd"
theme_colors = { accent = "#CBA6F7", heading = "#F9E2AF" }

CLI

The CLI can launch the TUI, inspect configuration, manage themes, or work with notes non-interactively while Markdown files remain the source of truth.

General commands

CommandWhat it does
jotmdOpen the interactive TUI.
jotmd --helpPrint command and option help.
jotmd --versionPrint the installed version.
jotmd --init-configCreate missing configuration and key-binding templates.
jotmd --init-themesExport missing bundled themes for customization.
jotmd --list-themesList available bundled and custom themes.
jotmd --dump-theme NAMEPrint one effective theme as TOML.
jotmd --dump-configPrint the effective configuration.
jotmd --dump-keysPrint the effective key bindings.
jotmd config check [PATH]Validate configuration, key bindings, editor, and theme.

Note commands

jotmd [--notes-dir PATH] search [--limit N] QUERY [--json]
jotmd [--notes-dir PATH] get PATH [--json]
jotmd [--notes-dir PATH] write [--if-revision REVISION] PATH [--json]
jotmd [--notes-dir PATH] delete --if-revision REVISION PATH [--json]
CommandWhat it doesOptions
search QUERYSearch note paths and contents.--limit N accepts 1–200 and defaults to 20; --json returns structured results.
get PATHRead an exact note and its revision.--json returns content and metadata.
write PATHRead content from stdin and create or update a note.Existing notes require --if-revision REVISION; --json returns metadata.
delete PATHPermanently delete one note.--if-revision REVISION is required; --json returns metadata.

Safe updates

write without --if-revision creates a missing note and refuses to overwrite an existing one. To update safely, read the current revision and send it back:

jotmd --notes-dir ./notes search "refresh token redis" --json
jotmd --notes-dir ./notes get projects/foo/pitfalls.md --json > /tmp/note.json
jq -rj '.content' /tmp/note.json > /tmp/note.md
revision=$(jq -r '.revision' /tmp/note.json)

# Edit /tmp/note.md, then update only if the note is unchanged.
jotmd --notes-dir ./notes write projects/foo/pitfalls.md \
  --if-revision "$revision" < /tmp/note.md

delete applies the same revision check and permanently removes one note. With --json, successes use stdout and errors use stderr.

Agent memory

The optional jot-memory skill lets Codex, Claude Code, and OpenCode recall and maintain durable Markdown notes through the JotMD CLI. The agent decides when substantial work needs recall and whether its result is useful enough to preserve.

CodexPersonal marketplace plugin
Claude CodeMarketplace plugin
OpenCodeGlobal linked skill

Prerequisite

Install JotMD, confirm it is on PATH, and run it once to select the vault used by both the TUI and agents:

brew install gonfff/tap/jotmd
command -v jotmd
jotmd

Agent-managed notes live below a reserved top-level directory:

agent-memory/
├── global/
└── projects/<project-id>/

Reserved directory. Before enabling the integration, move unrelated user content out of agent-memory/ or explicitly adopt it as agent-managed memory. Case variants are rejected.

JotMD hides this tree by default. Press a to show or hide it, or set show_agent_memory = true in config.toml to show it at startup.

Agent memory: Codex

Install

codex plugin marketplace add gonfff/jotmd
codex plugin add jot-memory@jotmd

Start a new Codex thread so the skill is loaded. Use codex plugin list to inspect the configured marketplace and plugin.

Update

brew upgrade jotmd
codex plugin marketplace upgrade jotmd
codex plugin add jot-memory@jotmd

Remove

codex plugin remove jot-memory@jotmd
codex plugin marketplace remove jotmd

Agent memory: Claude Code

Install

claude plugin marketplace add gonfff/jotmd
claude plugin install jot-memory@jotmd

Restart Claude Code after installation or update. Use claude plugin list to verify the plugin.

Update

brew upgrade jotmd
claude plugin marketplace update jotmd
claude plugin update jot-memory@jotmd

Remove

claude plugin uninstall jot-memory@jotmd
claude plugin marketplace remove jotmd

Agent memory: OpenCode

OpenCode discovers global skills under ~/.config/opencode/skills/<name>/SKILL.md. Keep a shallow checkout and link the skill so updates remain one command.

Install

git clone --depth 1 https://github.com/gonfff/jotmd.git ~/.local/share/jotmd
mkdir -p ~/.config/opencode/skills
ln -s ~/.local/share/jotmd/skills/jot-memory \
  ~/.config/opencode/skills/jot-memory

Update

brew upgrade jotmd
git -C ~/.local/share/jotmd pull --ff-only

Remove

unlink ~/.config/opencode/skills/jot-memory

Restart OpenCode after installation or update.

Verify agent memory

Start a new agent session in a Git repository and ask it to perform substantial research or implementation. The agent should consider memory before the work and report every memory note it changes afterward. Trivial requests intentionally skip memory.

Memory is ordinary Markdown: you can inspect and edit it directly, and JotMD can reveal it in the same vault when needed.

Development

just run       # run from the checkout
just build     # build bin/jotmd
just test      # run tests
just check     # format check, vet, and tests

Source code, releases, and issue tracking live on GitHub. JotMD is distributed under the MIT License.