Skip to content

About

A quiet corner before the busy work — sticky notes, a breathing exercise, and a thoughtful quote, tucked at the edge of your screen

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

Marginalia

MIT License Trivy Gitleaks Zero dependencies CLAUDE.md

A quiet corner before the busy work — a breathing circle, a thoughtful quote, book picks, and sticky notes tucked at the edge of the screen. Notes save only to your own browser (localStorage) by default; nothing leaves your device unless you opt into the optional sync feature below.

Features

  • Breathing circle — a slow, four-phase breathing prompt (Breathe in / Hold / Breathe out / Hold) to sit with for a moment before anything else.
  • A quote to sit with — rotates on its own, or tap "Another" for the next one. Tap "Keep" to tuck the current quote straight into Keepsakes.
  • Book picks — three random suggestions from a small, hand-picked shelf; tap "Shuffle" for a new set.
  • Sticky notes — a slide-out drawer of notes you can add, edit, delete, and drag to reorder, saved only in your own browser. Each note carries a date, with Newest/Oldest buttons to sort the list.
  • Keepsakes — a second margin tab next to Notes. Tap the ❧ on any note (or "Keep" on a quote) to move it into Keepsakes: sealed, read-only, chronological, stamped with the date you kept it. For things worth not losing, as opposed to things to do. Tap ↩ on a keepsake to move it back into Notes if it needs an update.
  • Copy — every note and keepsake has a "Copy" control next to its date, for pasting the text elsewhere.
  • Optional cross-device sync — deploy your own Cloudflare Worker (see worker/) and paste its URL/key into the sync settings panel to sync both notes and keepsakes across devices. Off by default; see Storage & Privacy below.
  • Optional "Reflect" (bring your own model) — tap "Reflect" on any note to get one short reflective question or small mental exercise related to it, generated by an LLM using your own API key (paste it into the "AI" settings panel next to the sync gear). One-shot, no chat thread, no message history — and the result is only saved if you tap Keep. Off by default, and no note content ever leaves your device unless you explicitly tap Reflect on that note.
  • "From your margins" — a third panel under the book picks, same rhythm as the quote panel (tap "Another" for a new one, "Keep" to save it), but personal: the prompt is built from a sample of what's actually in your Notes and Keepsakes, using the same bring-your-own-model setup as Reflect. Tap-to-generate only — nothing is sent just from opening the page.
  • Illustrated background, your choice — a faint engraved plate sits behind the page: the default is a pair of Bewick birds, or pick a botanical plate, a hand-coloured Merian plate of butterflies and a pomegranate, or turn it off entirely, from the "BG" button next to the sync gear. Purely decorative, and the choice stays on your device only.
  • Installable — works as a home-screen / dock app on iOS and macOS Safari (which have no native install prompt), via a small in-page banner.
IMG_4471

Quick Start

git clone https://github.com/ANDRS-Projects/marginalia.git
cd marginalia
./setup.sh

Or skip cloning entirely and just try it hosted: https://andrs-projects.github.io/marginalia/

See CLAUDE.md for the full command reference and architecture.

Prerequisites

  • Any modern web browser
  • That's it. No runtime, no package manager, no build tool.

How it works

Marginalia is a single self-contained index.html file — no build step, no server, and no dependencies except a Google Fonts CDN stylesheet and a handful of real image files alongside it (the app icons, and the illustrated background plates). You can:

  1. Visit it hosted via GitHub Pages — the repo serves index.html from the default branch root at https://andrs-projects.github.io/marginalia/.
  2. Download and open it directly in any browser — right-click "Save As" (or git clone) and open index.html locally. It's fully offline-capable except for the one-time Google Fonts request.

Storage & Privacy

By default, this is the whole point of the release, so to be explicit:

  • Notes and keepsakes are each stored only in your own browser, via localStorage. There is no account, no sign-in, and no backend server involved.
  • Nothing is sent anywhere, and nothing is shared between visitors — your notes on your laptop are invisible to anyone else, including on the exact same hosted URL.
  • Clearing your browser data (or using a different browser/device) means a fresh, empty set of notes and keepsakes. That's expected, not a bug.

This stays true unless you deliberately opt into the optional sync feature. The app ships with a createListSync() factory (see CLAUDE.md) — a documented swap-in point for cross-device sync, instantiated once for notes and once for keepsakes — and its default implementation is a real, working one: a small Cloudflare Worker backed by two Cloudflare KV keys (see worker/). It is inert by default: nothing is sent anywhere until you deploy your own copy of the Worker (worker/README.md walks through it) and paste its URL and API key into the sync settings panel (gear icon next to the status pill in the notes drawer) — the same credentials cover both resources. Once configured, your notes and keepsakes leave your device and are stored in your own Cloudflare account, under your own Worker — never anyone else's, and never anything you didn't explicitly set up yourself. Want to sync through Notion, your own API, or something else instead? Replace createListSync()'s implementation with your own version of the same shape; nothing else in the file needs to change.

The "Reflect" action is a separate opt-in with its own credentials. Configuring sync does not enable Reflect, and vice versa — the two share no storage keys. Reflect stays inert until you paste a URL, API key, and model into the "AI" settings panel (button next to the sync gear); until then, tapping Reflect on a note just tells you it isn't set up. Once configured, that one note's text is sent to whatever endpoint you configured — by default, directly to Anthropic's API using your own key, which is a real, billable credential (unlike the sync feature's Worker key, a leaked Reflect key can cost you money on your own account, so treat it accordingly). No other note, keepsake, or app data is ever included in that request.

"From your margins" uses the same credentials as Reflect, but sends more. Configuring the AI settings panel enables both features together — there's no separate toggle. Where Reflect sends only the one note you tapped, "From your margins" samples up to six recent notes and six keepsakes and includes all of it in the prompt, every time you tap "Another" on that panel. Still tap-to-generate only (nothing is sent just from having the page open), and still your own key/endpoint — just a wider slice of your own content going out with each request.

Development

There is no dev server, build step, linter, or test suite — it's one static HTML file. To work on it:

open index.html                 # macOS
xdg-open index.html             # Linux
python3 -m http.server 8000     # or serve locally at http://localhost:8000

Edit index.html directly and reload the page to see changes.

Using with Claude Code

This project includes a CLAUDE.md that gives Claude Code full context.

claude    # Start Claude Code — reads CLAUDE.md automatically

License

MIT — see LICENSE

Contributing

See CONTRIBUTING.md

About

A quiet corner before the busy work — sticky notes, a breathing exercise, and a thoughtful quote, tucked at the edge of your screen

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages