DunneNote documentation
DocsDunneNoteConcepts

The .calnote format

Shipped

What is inside a notebook, and how to read one without DunneNote.

A notebook is a directory, and its contents are documented so that a third party can read one using nothing but standard tools — sqlite3, jq and sha256sum. This is deliberate. A note-taking application that can hold your work hostage is not much better than no note-taking application.

Layout

MyResearch.calnote/
├── format.json          self-describing manifest
├── notebook.db          SQLite database — pages, canvases, content
├── blobs/
│   └── sha256/
│       └── aa/bb/aabbcc….bin      content-addressed binary store
├── attachments/
│   └── pdf/report.pdf             user-facing linked files
└── .state/                        transient UI state — safe to delete

The manifest

format.json names the format version the notebook is written in and carries the notebook’s stable identity. That identity is what lets a link from another notebook keep resolving after this one is moved or renamed.

The database

notebook.db is an ordinary SQLite database. Pages, canvases, grid rows and columns, calendar events, links and the search index are all tables in it. You can open it with the sqlite3 command-line tool and look around.

Writes happen inside transactions, so an interrupted session leaves a consistent database rather than a partial one. SQLite’s own write-ahead log may leave notebook.db-wal and notebook.db-shm files behind after an unclean shutdown; they are normal, and SQLite’s recovery handles them.

Blobs and attachments

Images and other embedded binary content live in blobs/, addressed by the SHA-256 hash of their contents and sharded into subdirectories by the first four hex characters of that hash. Storing the same image on ten pages stores it once.

attachments/ holds files you have linked rather than embedded, under their own sanitised names. Unlike the transient files, attachments/ is durable content: any backup or sync tool must copy it alongside notebook.db and blobs/, or the notebook arrives incomplete.

Versioning and forward compatibility

The format carries a version, and the rules for what an older reader must do when it meets something new are written down rather than left to chance. An older version encountering a container kind it does not recognise must show an inert placeholder and — critically — must not delete it. Opening a newer notebook in an older build is allowed to lose display fidelity. It is not allowed to lose data.

Locking

A .calnote.lock file marks a notebook as open. It is advisory: it stops two DunneNote instances from writing to the same notebook at once, which is a different problem from stopping you copying the folder.