Svelte, in your repo
Blocks are real Svelte 5 components. Content and config are YAML. It’s a codebase, not a config screen.
A CMS that’s just files — and stays yours.
Your whole site is Svelte components and typed YAML in your repo. Point any CLI agent at it, edit across the codebase the way you would in SvelteKit, push, and hand your client a browser editor — without giving up the code or wiring up an API.
Every other tool makes you choose. Build in a framework and content is locked to people with a terminal. Reach for a headless CMS and your schema moves into someone else's admin, an API in the middle. Primo keeps the schema next to the component — fields.yaml beside the .svelte — and the editor your client uses is generated straight from it.
The block you edit as code and the page your client edits are the same files. No glue layer to build or babysit.
Blocks are real Svelte 5 components. Content and config are YAML. It’s a codebase, not a config screen.
Claude Code, Cursor, Codex, aider — they edit the whole site as files, the way they would any framework project.
Declare fields once; the client editor and the renderer both read the same schema. No translation layer.
Compiles to plain HTML. One Go binary, your infra, MIT-licensed. Export everything anytime.
Pull, change anything, push. Then your client picks up in the browser.
Components, pages, content, config, routes — all plain files in your repo.
$ primo pull my-site.primo.build
Point your agent at the repo. It works the whole site like any SvelteKit project.
$ claude "add a /vs/sanity comparison page"
Only what changed syncs to the server. Your client edits the same site in the browser.
$ primo push
The CLI reads a PRIMO_TOKEN from your environment — same auth an editor uses, no API surface to learn.
Not today. Primo is built around Svelte’s compile-time model — it’s what lets blocks be “just files” the editor and renderer both read directly. On the roadmap is primo integrate <framework> to layer Primo onto an existing SvelteKit (then Astro) app, where Primo owns content and the editor while your production components stay in the framework.
Payload keeps your schema in its admin and serves content via API. TinaCMS puts a git editor in front of markdown. Sanity is a React admin over a hosted content lake. Primo is none of those — the editor and the renderer read the same Svelte files and database rows, no API in between.
Code in your repo; content in SQLite via PocketBase on the server. primo pull exports both as static files at any time. MIT-licensed — nothing to get stranded behind.
Pull a site. Point your agent at it.
One command to spin up a workspace. It’s just files from there.
MIT · open source · free forever