Move
w s between notes, j k to scroll the one you are reading. Neither ever changes meaning.
A Markdown note taker that lives in your terminal — and in your browser, from the same 19 MB binary. One SQLite file on your own disk. Nothing running when you quit.
$ curl -L .../releases/latest/download/nib-linux-amd64 -o nib
The note you are reading fills the screen. Down the right-hand side sits a
small box of facts about it, and under that, the list of everything else.
Press ? and every key is listed without leaving the app.
w s between notes, j k to scroll the one you are reading. Neither ever changes meaning.
n for a new note, ↵ to edit. Leave the title blank and the first line becomes it.
Bold, italic, strikethrough, code, headings, three kinds of list, quotes and rules — all on keys.
/ narrows titles and bodies as you type. Under five milliseconds across a thousand notes.
d moves a note to a trash. u walks back, T browses thirty days of them.
Click a pane and ↑↓ and the wheel act on it — scroll the note, or step through the list. The live pane is the bright-bordered one.
R shows the raw Markdown with no borders, and hands the mouse back, so a selection is the text and nothing else.
The preview shows the link text, not the URL. Press o to open one — or pick from a list when the note holds several.
e opens the note straight in $EDITOR; ctrl+e does it mid-edit.
W opens the same notes in a React UI, served from inside the binary, bound to localhost.
Click a pane to aim at it. Click the note and ↑
↓ and the wheel scroll it; click the list and
they step between notes instead. Whichever you aimed at wears the
bright border, so there is always something on screen saying where
the next scroll will land.
w s and
j k ignore all of it.
They always mean “another note” and “scroll this
one” — so there is always a key whose effect does not
depend on where the mouse has been.
The honest cost: for the app to know which pane you clicked, the
terminal has to hand it the mouse, so selecting text on this screen
means holding shift while you drag. It is the
only screen that holds it — the editor, the trash, the help and
R all give the mouse straight back.
Aimed at the note — the wheel scrolls it.
Press ↵ at the end of a list item and the next
one is already waiting — tasks, bullets, numbers that keep counting,
blockquotes. Indentation is kept, so a nested item stays nested.
Press it once more on the empty item and the marker disappears. That is how a list is finished: no mouse, no menu.
alt+↵ gives a plain line break. Shift+Enter
cannot: a terminal sends the identical byte for it as for Enter.
In the browser, drag a picture onto the editor — or paste one, so a
screenshot goes from PrtSc to
Ctrl+V without ever becoming a file you have
to name and then find again.
In the terminal, drag the file onto the window. A terminal has no drag-and-drop of its own: it pastes the file's path. nib notices a paste that names only files that exist and attaches them instead. Anything else pastes as the text it is.
Every file is named after a hash of its own contents, so the same picture in three notes is stored once. Remove the line and the file waits thirty days in a trash before it goes — the same grace a deleted note gets.
The preview names a picture rather than drawing it. Terminals that
can show images need the kitty, iTerm2 or sixel protocol, and most
have none of them — so o opens the real file
in your own viewer. One thing in the note opens straight away;
several bring up a list to choose from.
The name you see is a real terminal hyperlink, so
ctrl-click opens the file too — though
o is the route that works everywhere.
# drag holiday.png onto the window  ~/.local/share/nib/ nib.db attachments/8f3a91c2d4e5f607.png
Measured in one sitting on one machine, every row the same way — wall clock around a subprocess, median of twenty-five runs. The first four are what each runtime costs before a line of your code runs.
The last row is not a floor. It is the whole job — opening the database, reading every note, standing up the server — and it finishes before Node has started up with nothing in it at all.
Go is not magic; a careful Rust or C build would beat it. What Go buys is that the fast path is the default one.
Measured on an Intel i5-13450HX running Ubuntu, with a thousand notes in the database.
These are real measurements, not estimates — but they are one machine on one afternoon, with everything in the page cache. Run them yourself and the absolute numbers will differ. The ratios are the part that travels.
Every note lives in one SQLite file on your own disk, with any files you attached in a folder beside it. Copy that folder and you have copied everything — there is no export, because there is nothing to export it from.
Nothing is destroyed in a hurry either. A deleted note sits in a trash for thirty days, an attachment nothing refers to gets the same thirty, and the database is snapshotted every time the app starts, keeping the last ten.
The browser interface binds to 127.0.0.1, so
nothing else on your network can reach it. No telemetry, no sync, no
server, no account to create.
Press W in the terminal and the same notes
open in a browser — a formatting toolbar, live preview and a
light or dark theme, for the times you would rather point at
something than remember a key.
Double-click the text and you are typing. A note
opens rendered, because rendered is how a note is worth reading —
double-click any part of it and the pane becomes its Markdown,
cursor already on the line you pointed at. It saves as you go, and
ctrl+s and esc still
mean what they mean in the terminal.
It is the same file, open twice. Write in one, press
r in the other and it is there. The page is
served from inside the binary, so there is nothing to install and
nothing to deploy.
Files open instead of downloading. A clip plays in
the paragraph you dropped it into, with its name underneath. A
.docx is converted and read in a tab of its
own, a .csv is drawn as a table, and a
picture or a video takes a corner you can drag to resize. All of it
happens in the page — nothing is uploaded anywhere to make it work.
Bound to 127.0.0.1, so it is reachable from
this machine and nowhere else. Press W again
and the server stops.
Ship Thursday if CI is green.
Whenever the web UI is running there is a small HTTP API beside it, on the same notes. Enough to write one from a shell script, wire up a hotkey, or pull everything out into a file.
The trash routes only act on trashed notes — a live note returns 404, so nothing can be destroyed without being trashed first.