a quiet place to write — together.
author* is a small, open-source collaborative writing app: a calm serif page with live multiplayer editing, an editor you can ask things of, comments, versions, and one-click publishing. A modern interpretation of the word processor — for anyone who writes, whether that's tweets, letters to your landlord, or the novel.
Live at author.computer.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ghost writing · live cursors · ⌘K rewrites · the proof
comments · versions · publishing · profiles · .md import
dark mode · the letterbox · rss · an mcp server
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- just start writing — no account needed. the landing page drops you
straight into a draft as a ghost. you get the full editor, live
collaboration, and one model request on the house. creating an account
(just an email and a password) carries everything you wrote with you —
five model requests a month are free, membership lifts the limit.
/newis the shortest way in: it always opens a fresh draft. - live collaboration — Yjs CRDTs over WebSockets; share a writing link and whoever opens it lands in the draft with you, named cursors and all
- an editor on call — ask streams feedback on the draft, the proof reads for exactly the checks you pick (grammar, clarity, clichés, hedging, your own…) with every issue clickable, and ⌘K rewrites any selection to instruction
- formatting — select text for the floating toolbar (bold, italic, underline, strike, code, headings, quotes, links), or type markdown and watch it convert; the usual ⌘B/⌘I/⌘U shortcuts all work
- pages — header images (any format — the browser recompresses),
comments in the margin worn as real highlighter ink
(highlighte.rs), named versions with one-click
restore, a history of writing sittings each one click from its diff,
publishing to a quiet read-only page at
/p/<slug> - the letterbox — open the slot and readers of your published pages
can leave an email address;
[ ✉ post ]mails a piece to every confirmed address, once, with one-click unsubscribe. postage is metered per writer and the post office has a ceiling it won't spend past - profiles — an optional public page at
/u/<handle>with your social links, a six-month writing contribution chart, whichever published pieces you choose to list (each page has its own toggle), and an rss feed at/u/<handle>/feed.xml - dark mode — a ☾ in every page's corner turns the paper warm-dark for anyone, ghost or passerby; it follows the OS preference until you choose, and the choice survives reload
- an mcp server — mint an API key in settings and Claude (or any MCP
client) can connect at
/mcp, read-mostly: list and read your drafts, read their comments, create new drafts — never a live editing session. keys are shown once, hashed at rest, revocable always - import — bring your writing with you: every
.mdfile becomes its own draft, titles from# headings, links and formatting intact
npm install
cp .env.example .env # add your Anthropic API key
npm run build # builds the client into dist/
npm start # serves everything on http://localhost:3001Two dev accounts are seeded on first run (ink / quill, password author). Open the same draft in two windows to see live editing.
- deploys anywhere a container runs (
Dockerfile);fly.tomlincluded — mount a volume at/app/dataso the database and images persist - required in production:
BETTER_AUTH_SECRET(random 32+ bytes) andBETTER_AUTH_URL(your origin) — the server refuses to boot without them - backups: with
BUCKET_NAME+AWS_*secrets set (on Fly:fly storage create), litestream continuously replicates the database to S3-compatible storage and restores it automatically onto an empty volume; without them the entrypoint warns that replication is off. images ride to the same bucket beside the words, best-effort, and a restored volume pulls them back down - the post office needs
RESEND_API_KEY(and optionallyEMAIL_FROM) to send real letters; without a key every send is a dry run that logs. letter volume and letterbox sizes have their own dials —EMAILS_FREE_MONTHLY,EMAILS_MEMBER_MONTHLY,EMAILS_GLOBAL_DAILY,SUBSCRIBERS_FREE_MAX,SUBSCRIBERS_MEMBER_MAX - ship with
npm run deploy— snapshots the volume, builds, deploys, and verifies prod serves the new bundle - model spend is tiered: ghosts get one request, free accounts get
AI_FREE_MONTHLY(default 5) per month, members getAI_DAILY_CAP(default 150) per day, and the whole site stops atAI_GLOBAL_DAILY_CAP(default 1000) per day. flip membership withnode scripts/set-member.mjs <handle> on
| layer | choice |
|---|---|
| editor | Tiptap (ProseMirror) + React + Vite |
| collab | Yjs — custom y-websocket server (server/collab.js) |
| auth | Better Auth — cookie sessions, anonymous ghosts, username + email login |
| server | Express + ws + better-sqlite3 (single file DB in data/) |
| editor brain | Anthropic API (claude-opus-4-8), server-side only, never in the browser |
| post | Resend — confirmation letters + posted pieces; every send is a logged dry run without a key |
| margin ink | @highlighters/core — comment marks and live selections as chisel-tip strokes |
| mcp | MCP over streamable HTTP at /mcp (server/mcp.js) |
| analytics | Seline — cookie-free page views + product events; editor URLs are masked client-side |
Contributions welcome — issues, PRs, wild ideas. Useful things to know:
- a shelf of suites lives in
scripts/*-test.mjs— collab sync, imports, the letterbox, mcp, rss, image backups, versions, diffs, and more — all runnable against any server viaAUTHOR_BASE/AUTHOR_WS_URL - security posture: bcrypt passwords, origin-checked mutations and websockets, sanitized public HTML, magic-byte-validated uploads, rate-limited credential endpoints — read the git history for the review trail
- keep the design quiet: whitespace over chrome, ascii accents over icons, serif for prose, mono for furniture.