How it works

Two ways in.

One source of truth.

Primo represents your whole site as plain files and database rows. The same site is editable two ways — by an agent in the codebase and by a person in the browser. Pick the track that fits how you build. The other one keeps working anyway.

The same files, two editors

Pull your site down and locally it's just files — Svelte components, YAML content and config, routes. Your agent can change anything in it. Push it back and those files sync to a relational database on the server, where your client edits the same site visually, right on the rendered page.

There's no API in the middle and no second copy to keep in sync. The block your agent edits as code and the page your client edits are the same files — the editor generates its fields straight from the block's schema, so there's no glue code to write or maintain.

Track B — if you build with AI, no terminal

Describe it to an agent

Tell Claude, Cursor, or any assistant what you want. It builds the site — pages, sections, copy, images — straight into a real Primo project. No CLI, no setup.

Watch a real site appear

Not a mockup — a fast, live site with the sections you actually need. Preview it in the browser as it builds.

Click anything and edit

New price, new photo, new headline? Click it on the page and type. No dashboard maze, no dev ticket — and nothing breaks the design.

Keep it, host it, hand it off

It’s a real Primo site you own. Host it yourself or with us, and hand the same browser editor to whoever runs it day to day.

Track A — if you build with code

Point any CLI agent at a Primo repo and it works across the whole codebase the way it would in Next.js or SvelteKit. Three commands frame the loop; the editor is where your client picks up.

i. primo pull

Pull your site as files

Blocks are Svelte components; content and config are YAML. Pages, blocks, content — all in your repo as plain files. Scaffold a new site or pull an existing one.

$ primo pull my-site.primo.build
✓ pulled 14 blocks · 6 pages · content + config
ii. agent · do stuff

Let your agent change anything

Point Claude Code, Cursor, Codex — any CLI agent — at the repo. It edits across the whole codebase, components and content alike.

$ claude "redesign the pricing page"
▸ editing blocks/pricing · 3 files changed
iii. primo push

Push it back

On push, your files sync to a relational database on the server. Only what changed is uploaded. Same auth an editor uses — no API surface to learn.

$ primo push
✓ synced · live in the editor
iv. editor · hand off

Your client edits in place

They open the browser and edit the same site on the rendered page, with the exact fields your blocks declared. The schema generates the editor — no glue code.

$ # nothing to run — it just works
▸ on-page editing · real-time collab · drag-drop blocks

Same source of truth, two ways in. Files locally · a database on the server · the CLI reads a PRIMO_TOKEN from your environment.

Questions about the workflow

Do my agent's edits and my client's edits ever conflict?

They edit the same source of truth, not two copies. Locally it’s files; on the server it’s database rows synced from those files. primo pull brings the latest server state back down before your agent works, and primo push uploads only what changed — so there’s no second copy drifting out of sync.

Does the client need the terminal or the CLI?

Never. The CLI is the developer track. Clients (and AI-first makers) only ever touch the browser editor — click-to-edit on the rendered page, drag-and-drop blocks, and a structured form view for the fields that aren’t visible on the page.

Where does the editor's UI come from?

From your block’s field schema. Each block declares its fields in fields.yaml next to the .svelte component; the editor reads that schema and generates the editing surface. No separate CMS config, no translation layer.

What happens to my site if I stop using Primo?

Your content lives in SQLite (via PocketBase) and your code lives in your repo. primo pull gives you a static export of both at any time, and Primo is MIT-licensed — the site you’ve built keeps running.

Build it with an agent. Hand it to a human.

One command to spin up a workspace. Point any agent at the repo, then hand your client the browser.

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

MIT · open source · free forever