For developers

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.

Own the code. Hand off the editing.

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.

What you actually get

Svelte, in your repo

Blocks are real Svelte 5 components. Content and config are YAML. It’s a codebase, not a config screen.

Any CLI agent

Claude Code, Cursor, Codex, aider — they edit the whole site as files, the way they would any framework project.

Schema-generated editor

Declare fields once; the client editor and the renderer both read the same schema. No translation layer.

Static + self-hosted

Compiles to plain HTML. One Go binary, your infra, MIT-licensed. Export everything anytime.

The loop you already know

Pull, change anything, push. Then your client picks up in the browser.

i. primo pull

Pull the site as files

Components, pages, content, config, routes — all plain files in your repo.

$ primo pull my-site.primo.build
✓ pulled · components + content + config
ii. agent

Edit across the codebase

Point your agent at the repo. It works the whole site like any SvelteKit project.

$ claude "add a /vs/sanity comparison page"
▸ 4 files changed
iii. primo push

Push back, hand off

Only what changed syncs to the server. Your client edits the same site in the browser.

$ primo push
✓ live · on-page editing enabled

The CLI reads a PRIMO_TOKEN from your environment — same auth an editor uses, no API surface to learn.

Developer FAQ

Can I use React instead of Svelte?

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.

How is this different from Payload, TinaCMS, or Sanity?

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.

Where does my content actually live?

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.

$ npx primo-cli init my-workspace
✓ workspace ready · server.yaml written

MIT · open source · free forever