DunneNote · Open format
The open .dunnenote format
What is inside a notebook folder, how the format is published, and how to read a notebook without DunneNote.
A notebook is a folder, and its layout is published so that anyone can read it
with standard tools such as sqlite3, jq and sha256sum. That is deliberate.
Your notes should not depend on one app to be readable.
DunneNote the app is commercial. The format is open: its schema, its specification and a library that reads and writes notebooks are licensed under MIT, so anyone may build on them. All of them are public on GitHub. See the open-format page for the overview, and dnfmt and the format library for the tool.
What is published#
| Piece | Status |
|---|---|
| This page: the layout and the rules below | Available |
| The specification (DunneNote Format 0.18, draft) | Available |
| The schema: every table, index and trigger at the current version, generated from DunneNote itself | Available |
dnfmt and the dunnenote-format library: read, verify, export | Available (0.1.0) |
| Writing notebooks with the library: every canvas kind, forms, templates, tags, archiving | Available (0.1.0) |
The format is a 0.x draft while DunneNote is before 1.0. It will be frozen as 1.0 when DunneNote reaches 1.0. Until then, every change carries a new version number and a changelog entry, and the library states exactly which versions it reads.
Layout#
MyResearch.dunnenote/
├── format.json manifest: format, version, notebook identity
├── notebook.db SQLite database: pages, canvases, content, search index
├── blobs/
│ └── sha256/
│ └── aa/bb/aabbcc….bin pictures and other binary content, by hash
├── attachments/ durable files, e.g. a form's answers written to a file
├── .settings/ this notebook's settings
├── .archive/ snapshots of archived pages and sections
├── .state/ transient UI state, safe to delete
└── .dunnenote.lock present while the notebook is open
You may also see SQLite's own notebook.db-wal and notebook.db-shm files.
They are normal: SQLite creates them for anything that opens the database,
including DunneNote and dnfmt.
The manifest#
format.json is a small JSON file. Its format field is always "dunnenote",
format_version names the format version the notebook was created with, and
notebook_id is the notebook's permanent identity. That identity stays the same
when the folder is moved or renamed, which is what lets links from other
notebooks keep resolving.
The database#
notebook.db is an ordinary SQLite database. Pages, canvases, table rows and
columns, calendar events, tags and the search index are all tables inside it.
Its user_version is the schema version: 18 for the current format,
0.18.0. You can open it with the sqlite3 command-line tool and look around.
Only do this on a copy, or while DunneNote is closed.
Changes are written inside transactions, so an interrupted session leaves the database consistent rather than half-written. The search index is a cache that DunneNote rebuilds when it is empty, so a tool never needs to maintain it.
Blobs#
Pictures and other binary content live in blobs/sha256/, named by the SHA-256
hash of their contents and split into subfolders by the first two pairs of hex
characters. The same picture used on ten pages is stored once. You can check any
blob with sha256sum: the output should match its file name.
Attachments and archive snapshots#
attachments/ holds durable content, such as a form's answers when you choose
to write them to a file. .archive/ holds a compressed snapshot for each
archived page or section. The pages themselves stay in the database, marked as
archived, so the snapshots are a safety copy, not the only copy.
If you copy a notebook with other tools, copy the whole folder. Copying only
notebook.db and blobs/ leaves out attachments and settings.
Newer and older versions#
The format carries a version number, and there are written rules for what a
reader must do with content it does not recognise. A canvas of an unknown kind
is shown as a placeholder and is never deleted. DunneNote refuses to open a
notebook whose format is too new for it rather than risk damaging it. dnfmt
follows the same rules: a notebook one version newer than it knows opens
read-only, and anything newer is refused.
The lock file#
.dunnenote.lock marks a notebook as open. It stops two copies of DunneNote
from writing to the same notebook at once. It is advisory, so it does not stop
other tools from copying or changing the folder. Close DunneNote before you copy
a notebook with anything else. dnfmt's reading commands never take the lock
and can tell you whether DunneNote has the notebook open. Its editing commands
take the lock while they work and refuse a notebook that DunneNote has open.
Checking a notebook#
In Settings ▸ Backup, Check each notebook for damage when it opens runs a health
check each time you open a notebook. It is on by default. Outside the app,
dnfmt verify runs the same kind of check. See
Check a notebook with dnfmt.
Related#
Something unclear or out of date? Open a support ticket.