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 21 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 as a block editor — drag to reorder, / to insert — 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 note you write straight into, a slash menu
for anything you want to insert, and a light or dark theme, for
the times you would rather point at something than remember a key.
There is no edit mode. A note is one surface and
typing into it is how it changes — a heading looks like a heading
while you write it, a table is a table you can put the cursor in.
Type / to insert anything; select text and a
toolbar appears over it. It saves as you go, and what lands on disk
is still the Markdown the terminal reads.
Every block has a handle. Point at a paragraph, a
heading or a table and two controls appear in the margin:
+ inserts a block under it, and the six dots
do the rest. Drag them and the block moves, with a line showing
where it lands; click them for Duplicate and
Delete. The toolbar stays at the top as you
scroll, so the controls are in the same place on line four hundred
as on line one.
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.