Copydesk
Publishing tool, front to back
A writing and publishing tool that gets out of the writer’s way — a clean canvas backed by a serious engine.
- Year2026
- Runs onWeb
- DisciplineEngineering & DevOps

A sample brief, a real product. We wrote this brief ourselves to show how we work; the client and their story are illustrative. The product is not: it was designed and engineered here, and you can use it below. We publish results only for work a client has let us verify, so this page shows none.
The brief
Copydesk wanted the calm of a blank page with the power of a real publishing platform underneath. We designed and built both halves.
The problem
Editors are unforgiving — a single janky keystroke and writers leave. The interface had to disappear while the engine did heavy lifting.
- A rock-solid, distraction-free editor
- Real-time save and version history
- Publishing that just works, everywhere
- Performance that never stutters mid-sentence
The approach
We obsessed over the editor first — latency, selection, undo — then built the platform it deserved.
- A custom editor tuned for zero-lag input
- Versioning and autosave you never think about
- A typed API and clean publishing pipeline
- Motion and chrome kept nearly invisible
What shipped
- Toolbar and keyboard shortcuts
- Slash commands
- Outline
- Versions with restore
- Focus mode
- Schedule and publish
- Posts list with drafts, scheduled and published
- Media library and tags
- Comment moderation
- Newsletter with issues
Under the surface
How it is built
Remix on Node renders MDX documents from PostgreSQL, Meilisearch powers instant search, media flows straight to S3 with presigned uploads, and everything ships as one Docker image.
- MDX pipeline with custom shortcodes, sanitised
- Presigned S3 uploads — media never touches the app
- Single-container deploys, zero-downtime swaps
Considered and turned down
Next.js + Contentlayer was close; Remix’s nested routes matched the editor/preview split better.
Stack
The mechanism, working
The part of Copydesk that was hardest to get right, as a small model you can operate.
Zero-lag editor with history
Input is committed locally on the same frame; snapshots are versioned in the background.
