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.
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.
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.
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.
Not a mockup — a fast, live site with the sections you actually need. Preview it in the browser as it builds.
New price, new photo, new headline? Click it on the page and type. No dashboard maze, no dev ticket — and nothing breaks the design.
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.
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.
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
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"
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
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
Same source of truth, two ways in. Files locally · a database on the server · the CLI reads a PRIMO_TOKEN from your environment.
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.
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.
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.
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.
MIT · open source · free forever