Primo vs Sanity.
Sanity is one of the best headless CMSes there is — structured content done right, a genuinely powerful React Studio you can customize to the hilt, and a content model built to feed web, mobile, and whatever surface comes next. So this isn’t a takedown. The real difference is architectural: with Sanity your content lives in their hosted content lake and your app fetches it over an API, while editors work in a separate Studio admin. With Primo, the content is files in your repo, there’s no API to fetch, and your client edits in place on the rendered page itself.
…you have large, highly structured content feeding many channels (web, mobile, in-store, syndication), a sizeable editorial team, and you want a customizable React Studio plus real-time collaboration out of the box. For big content operations, Sanity’s content lake and GROQ model are genuinely excellent.
…you’re building a content site to hand to a client and you want to own the content outright — no hosted lake, no API layer, the file your agent edits as code being the same file your client edits on the page. Self-host, MIT, and Svelte today.
Where they actually differ
Structured content, done at scale.
Be fair first. Sanity is excellent at the thing it's designed for: highly structured, reusable content modeled once and delivered everywhere. Portable Text gives you rich content that isn't trapped in HTML, GROQ lets you query exactly the shape your app needs, and the content lake is built to feed many surfaces at once — website, native app, kiosk, syndication. If your content is an asset that outlives any one front-end, that model is the right one.
And Sanity Studio is a genuinely great editing environment — a React admin you can customize deeply, with real-time collaboration, granular validation, and tailored input components. For a large editorial team working in parallel on a big content graph, that power is exactly what you want, and Primo isn't trying to replace it.
A hosted lake and an API, vs files you read directly.
Here's the mechanism, stated plainly. With Sanity your content lives in their hosted content lake. Your front-end fetches it over an API — you write GROQ queries, pull the data, and render it. Editors, meanwhile, work in Sanity Studio, a separate React admin that is not your rendered site. The Studio writes to the lake; your app reads from the lake. It's a clean decoupling and it's exactly why one content set can feed many front-ends.
Primo collapses that. The whole site — blocks, pages, content, config — is plain files in your repo, and on the server it lives in a lightweight store you own (SQLite via PocketBase). There's no hosted lake holding your content and no API layer to query — the renderer reads the files directly. A block is a Svelte component plus a fields.yaml beside it, and the editor generates its UI from that field schema. So the block your agent edits as code and the page your client edits are the same files, with no glue code in between.
Your client edits the page, not a dashboard.
With Sanity, the editor lives in Studio. A non-technical client logs into a separate admin, edits fields in forms, and then sees the result on the site after it's fetched and rendered. That round trip is fine — often ideal — for a content team that thinks in terms of structured documents feeding multiple channels.
With Primo, the client opens the actual site and edits it in place: click a heading and type, swap an image, reorder sections — on the rendered page, not in a dashboard. There's no API call between the edit and the result because the page is the source. For a freelancer or agency handing a finished site to one client, that's a smaller, more direct surface to teach and to maintain.
Sanity for big content ops; Primo for content sites, in Svelte.
If you're running a large structured-content operation — many editors, content feeding web plus mobile plus other surfaces, deep custom validation and workflows — Sanity's content lake, GROQ, and customizable Studio are hard to beat, and we won't pretend otherwise. That's its home turf.
Primo is built for the other shape: custom content sites — marketing sites, portfolios, local-business sites, landing pages — the kind a freelancer or agency builds and hands off to a single client. And today Primo's blocks are Svelte, not React. That's the trade that lets blocks be "just files" the editor and renderer both read directly. If you need React or a multi-channel content graph today, weigh that honestly.
Questions developers ask
Is Sanity's content lake a bad thing?
No — it’s a deliberate, well-built design, and it’s the reason one content set can feed web, mobile, and other channels cleanly. The point isn’t that it’s wrong; it’s that your content lives in their hosted infrastructure and your app reaches it over an API. Primo makes a different trade: content is files in your repo and self-hosted SQLite, read directly with no API, at the cost of being a single-site, Svelte-first tool today.
Do both let my client edit content?
Yes, but in different places. Sanity gives editors Studio, a separate React admin that writes to the content lake — powerful and collaborative, but not your rendered site. Primo lets the client edit in place on the live page: the editor is generated from each block’s field schema and reads the same files the renderer does, so there’s no separate dashboard.
Can I query Primo content with GROQ or an API like Sanity?
No — and that’s intentional. There’s no hosted lake and no API layer in Primo because the renderer reads the files directly. Content/config are YAML, blocks are Svelte components, and on the server it’s SQLite via PocketBase. If your architecture depends on querying a content graph from many front-ends, Sanity is the honest pick.
What happens to my content if the company disappears?
With Primo you’re covered: content lives in your repo + self-hosted SQLite, and primo pull gives you a static export of both code and content at any time. It’s MIT-licensed, so there’s no lock-in. Sanity Studio is open source, but your content sits in their hosted content lake, so check their export options if portability is a hard requirement.