Sanity

sanity.io

ALMOST

A weekend of work, and real gaps remain.

A headless content platform where the editing interface is itself code: you define the schema and the studio in your own repository, and it hosts the content and the API.

Promptfree, for everyone, and the only version there is
Build the content layer I actually need instead of Sanity — and know which half is hard.

**Real-time collaborative editing.** Two editors in the same document, with presence, converging correctly. That is the part you should not write, and the answer is an existing conflict-free replicated data type library rather than a homemade one.

The rest — a schema, an editing screen, an API — is a fortnight, and it fits your content better than a generic one.

STACK
- Node 20+ with Fastify, server-rendered HTML for the editing screens
- SQLite through better-sqlite3, WAL mode, with FTS5
- Yjs if you genuinely need simultaneous editing; a per-document lock if you do not
- Caddy in front

THE DATA MODEL
- types: id, name, fields_json — the schema, defined in files in your repository and versioned with the code that renders it
- documents: real tables per type, created and altered by generated migrations. **Not a generic key-value store** — real columns mean real constraints and queries that stay fast
- revisions: id, document_id, field, old_value, new_value, actor_id, at — append-only
- drafts: a separate row from the published document, so an unfinished edit is never what a reader sees
- assets: id, path, sha256, mime, bytes, width, height, alt, focal_x, focal_y
- references between documents as real foreign keys, so a delete cannot orphan a page

DRAFT AND PUBLISH, WHICH IS THE PART THAT MATTERS
- Every document has a draft and a published version. Editing touches the draft; publishing copies it across, in one transaction, with a revision row
- **A preview URL that renders the draft**, so somebody can see the page before it exists. That is the feature editors actually judge the system by
- Scheduled publishing by a worker that is idempotent
- Unpublishing leaves the document and clears the published version, so nothing is lost by accident

COLLABORATION, HONESTLY
- If two people genuinely edit one document at once: Yjs, with the server as a relay and a periodic persist. Writing your own is a research project and getting it subtly wrong loses somebody's writing
- If they do not: a per-document lock with a visible indicator of who is editing. Worse, never destructive, and it is the right trade for most content teams. **Choose deliberately and write down which**

THE API
- REST per type with filtering, field selection, reference expansion and pagination
- Draft content requires a token; published content is public and cached hard with an ETag
- Webhooks on publish, signed and retried, so the site rebuilds itself
- A statement timeout and a row cap on everything

ASSETS
- Uploads streamed to disk, type from content, stored by hash, EXIF stripped including location
- Transformations on demand with **signed parameters**, or nobody can stop your server being used as a free image farm
- A focal point per image so cropping keeps the subject, which is a stored coordinate rather than a model

WHAT MATTERS MOST
Draft-and-preview, and real columns. The first is what makes editors trust the system; the second is what stops it becoming slow and unconstrainable once there is content in it.

What you lose

  • Real-time collaborative editing with presence, which is a distributed-systems problem rather than a feature
  • A hosted content API with a query language and a CDN in front
  • An editing studio that is code you control but hosting you do not
  • Asset handling with transformations, already built

If you would rather not build

  • Markdown files in the repository, if nobody non-technical edits
  • Yjs, for the collaboration half rather than writing one

The escape hatch

open source · no votes, no paid placement

Payload

$0

A code-first headless CMS with a generated admin and a real database underneath.

payloadcms/payloadfree · open source

Directus

$0

Wraps an existing SQL database with an admin and an API.

directus/directusfree · open source

Why this verdict

our own opinion · changed only by a person

48/100

Verdict kinda at 48: the schema and the API are ordinary, and real-time collaborative editing is the part to take from a library rather than write. Draft-with-preview is what editors actually judge it on.

History

tracked since 14 Aug 2026 · nothing is ever overwritten

Interest · last 30 days

Nothing recorded yet. This chart fills in once the page has visitors, votes or prompt copies — it will not draw a flat line to look busy.

Questions about Sanity

answered from the record above

Is Sanity free?

No — the plan we track is $15 a month. Growth at $15 per user per month billed monthly, plus usage above the included allowance; a free tier covers small projects.

Can you replace Sanity by building your own?

ALMOST. A weekend of work, and real gaps remain. Replacement score 48 out of 100, build time a weekend. Read what you lose before you decide.

How much does Sanity cost?

$15 a month on Growth — $180 a year. Recorded 14 Aug 2026.

What do you lose by replacing Sanity?

Real-time collaborative editing with presence, which is a distributed-systems problem rather than a feature; A hosted content API with a query language and a CDN in front; An editing studio that is code you control but hosting you do not; Asset handling with transformations, already built. If any of those carry weight for you, keep paying.

Is there an open-source alternative to Sanity?

Yes: Payload, Directus. The prompt on this page is for when you want it your way instead.

Related entries

same category first, most replaced first

All 16 in No-code apps & databases

Not sending yet

Every week, something stops being worth paying for.

New verdicts, prices that moved, entries added. One email a week. Unsubscribe in one click. Nothing is being sent yet — your address is kept here, and the first issue is the first thing it is used for.

free forever · no tracking pixel · stored here, never passed to anyone

Esc