How ForkLeaf works

ForkLeaf has an unusual shape for a notes app: there is no notes database. This page explains what there is instead, and what follows from that.

The shape of the thing

Your browser                          Our server              GitHub
────────────                          ──────────              ──────
[ editor ]                            [ session cookie ]      [ your repo ]
    │                                        │                      │
    ├──► IndexedDB  (source of truth,        │                      │
    │      instant, offline)                 │                      │
    │                                        │                      │
    └──► sync queue ──► /api/gh/* ──────────►│──► GitHub API ──────►│
                        (adds your token,        commits             .md files
                         never returns it)

Notes live in two places: IndexedDB in your browser, and files in your GitHub repository. There is no third copy on a ForkLeaf server. The server exists only to hold your encrypted session cookie and to proxy calls to GitHub with the token attached.

Local-first, not offline-mode

“Offline mode” usually means an app degrades when the network drops. ForkLeaf is the other way round: the local copy is always the one you are editing, and the network is a background job that catches the repository up.

Every keystroke goes to IndexedDB first

Debounced by a few hundred milliseconds, then written. This is why the editor never blocks on a request, and why a flaky connection cannot lose a sentence.

Changes queue as intents, not snapshots

The queue holds “this path changed, here is the new content, here is the SHA it was based on”. Repeated edits to one note collapse into one pending change instead of stacking up.

The queue drains when it can

On reconnect, on a timer, or immediately when you press ⌘S. A failed push leaves the change in the queue and says so in the status bar.

Why commits, specifically

A note could have been stored as a row in a table. Storing it as a file in a git repository buys several things that are hard to add later:

  • Version history you already trust. Not a bespoke “note history” feature — actual commits, with diffs, that you can revert with git revert.
  • Storage that is not ours to meter. GitHub is already hosting the files, which is why there is no storage tier to buy.
  • An exit that costs nothing. git clone and you have everything, in a format every other Markdown tool reads.
  • Interoperability by default. The same file renders on github.com, opens in Obsidian, and builds in Hugo or Jekyll.

Multi-file operations go through GitHub’s tree API as a single atomic commit, so renaming a note — which is a delete plus a create — can never half-apply.

How the code is arranged

ForkLeaf is a pnpm monorepo. Each package has one job and no knowledge of the UI, which is what keeps the sync logic testable without a browser.

PackageResponsibility
@forkleaf/typesThe shared domain model. No logic.
@forkleaf/markdown-engineFront matter, parsing, sanitised rendering, path helpers, document stats.
@forkleaf/github-clientThe GitHub REST client: trees, file reads, atomic multi-file commits, commit squashing.
@forkleaf/storeIndexedDB storage, the change queue, the sync engine, and conflict detection.
@forkleaf/diagramsMermaid rendering, the graph model behind the visual builder, templates, error mapping.
@forkleaf/editorThe editing surfaces: Tiptap for rich text, CodeMirror for source, and the diagram studio.
@forkleaf/exporterMarkdown, HTML, Word and PDF generation.
apps/webThe Next.js application: routes, API proxy, and chrome.

What ForkLeaf deliberately does not do

Being clear about this is more useful than a longer feature list.

  • Real-time collaborative editing. Two cursors in one document needs a server holding shared state, which is exactly the thing this design does not have. Concurrent edits are handled as conflicts, not merged live.
  • Server-side rendering of your notes. Exports run in your browser. Nothing is uploaded to be turned into a PDF.
  • Storing your notes. There is no table to leak.