Sanity-compatible · self-installing · yours
A CMS you own outright, deployed with one button
New Orange CMS is a content platform that runs entirely inside your own Vercel project and your own Supabase database. It speaks the Sanity API, so @sanity/client, next-sanity and a full Sanity Studio connect to it unmodified — and this site is one of its deployments, seeded and served by the thing it describes.

Built on
Ordinary infrastructure, arranged carefully
Nothing here is bespoke where something standard would do. Every piece below is something you can read, replace or take with you.
Sanity Studio v6
The real editor, forked and rebranded, served from /admin of your own deployment — with its validation, reference inputs and Portable Text editing intact.
GROQ, via groq-js
The same parser Sanity’s own tooling uses, over a SQL-narrowed candidate set — so full query semantics, not a subset that fails quietly.
Postgres, on Supabase
Documents, drafts, revisions and a full-text index in a database you provisioned, under row-level security, with plain SQL migrations.
Next.js 16, App Router
The reference frontend, and the only place the platform touches a framework. Server Components, incremental regeneration, exact cache invalidation.
Vercel Blob and Image Optimization
Asset bytes addressed by their content hash, delivered through your own routes with a practical subset of Sanity’s transform grammar.
Supabase Auth
Sessions in your own project, four roles enforced twice — once in the API for Sanity-shaped errors, once in Postgres so a bug cannot become data loss.
What it supports
Status is a closed vocabulary in the schema, so a partial implementation cannot be quietly presented as finished. The compatibility page has the same claims per surface, including what is out of scope.
| Feature | Status | Notes |
|---|---|---|
| @sanity/client and next-sanity, unmodified | supported | Queries, mutations, actions, listeners, uploads and the calls the Studio makes on boot, against any well-formed pinned API version. |
| GROQ: projections, joins, functions, slices, nested queries | supported | Evaluated by groq-js over a candidate set the planner narrows. Narrowing decides speed, never the answer. |
| Perspectives: published, drafts, previewDrafts, raw | supported | Including the draft-over-published overlay’s _id and _originalId rules. |
| Drafts, publishing and document actions | supported | create, edit, publish, discard, delete and unpublish, each applied as one Postgres transaction. |
| Mutations, patches and optimistic concurrency | supported | The whole patch set including diffMatchPatch, with ifRevisionID compared against the stored revision. |
| Reference integrity and unique published slugs | supported | Enforced by the platform on write and on publish, not only by Studio validation. |
| History: revisions, events and the transaction log | supported | Deletions included, which a history derived from current documents cannot report. |
| Real-time listen | supported | A genuine server-sent-event stream over Supabase Realtime, with keepalives and a polling fallback. |
| Assets: uploads, content-addressed ids, browser-direct upload | supported | Bytes in Blob, metadata in Postgres, URLs derived from the request origin at read time. |
| Identity: sessions, four roles, row-level security | supported | New accounts arrive with a role that grants nothing at all until an administrator elevates them. |
| Image transform parameters | partial | w, h, fit, q, fm, auto=format and dpr are served. Hotspot rectangles, blur, sharpen, rect, palette and LQIP are not. |
| Full-text search | partial | text::match pushes down to a Postgres tsquery. The result set matches; the ranking is Postgres’ rather than Sanity’s. |
| Presence, comments and tasks | partial | Stored, served and surfaced in the Studio; not yet at parity with the hosted product. |
| Sanity’s hosted services — Content Lake, scheduling, releases, Canvas | unsupported | Out of scope by design: this platform replaces the backend rather than proxying one. |
Every row above is a document in this deployment, and every feature has a page of its own under /features.
Read the documentation
Ten sections, forty-two pages — all of it content in this deployment’s own database, written in the Studio and rendered by the same pipeline as everything else on this site.
Getting started
What this platform is, how to deploy one in a click, how to run it on your own machine, and what is in the repository.
Content modelling
Schema types, the page-builder pattern, Portable Text, references and validation — the decisions that shape everything downstream.
The Studio
The editor at /admin: what the fork changes, how to shape the desk, how drafts and publishing work, and how preview is wired.
Content API
The Sanity-compatible HTTP surface: fetching, mutating, document actions, history and the real-time stream.
Querying
GROQ against Postgres: how queries are executed, what the perspectives mean, how search works and how to keep a query fast.
Assets
Uploading images and files, what an asset id means, which transform parameters are served, and how bytes are delivered.
Identity and access
Signing in, the four roles and what each may do, and the row-level security that enforces them a second time.
Frontend
Putting a Next.js site in front of the API: reading content, rendering Portable Text and images, caching, and previewing drafts.
Operations
The build pipeline, environment variables, database migrations, and the free-tier limits that are real.
Reference
The route table, the GROQ support matrix, the CLI, and the compatibility notes in full.
Deploy one, then take it apart
One button provisions the database and the storage, and the first build migrates the schema, creates an administrator and seeds a working dataset. The repository is public, and so is the reasoning behind it.
