v3.1 · open-source CMS · since 2019

Build sites with Claude Code.
Manage them visually.

Primo represents your entire site as files and database rows — natively editable by agents and humans,
so you can build websites with AI and hand them off to your clients and friends.

~/freelance/okafor-coaching · claude
> mira wants a pricing page with three coaching tiers before friday
claude (claude-opus-4-7)
I'll scaffold a pricing page-type so she can edit copy and prices herself once it's live.
Read (pages/index.yaml)
167 lines
Glob (blocks/**/fields.yaml)
11 matches
Write (pages/pricing.yaml)
+42 lines
Write (blocks/pricing-tiers/component.svelte)
+138 lines
Bash (primo push)
pushed 3 files
Pricing page is live. Mira can edit tier copy from the browser.
okafor.coach/pricing
Pricing
Simple, honest pricing.
Start free. Scale when you're ready.
Self-host
Free MIT
— Unlimited sites
— Visual editor
— Agent CLI
Choose
Hosted
$0 per mo
— Unlimited sites
— Visual editor
— Agent CLI
Choose
Team
$24 per seat
— Unlimited sites
— Visual editor
— Agent CLI
Choose
How it works

Pull your whole site down as files. Change anything.

Components, pages, content, config, routes — all synced as plain files via the pull/push round-trip. Agents work across the entire codebase, the way they would in Next.js or SvelteKit, without losing the visual editor your team uses every day.

i. primo init

Your whole site lives as files.

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

Components + Schema + Content
ii. agent · do stuff

Let your agent change anything.

Point Claude Code, Cursor, Codex — any CLI agent — at the repo. They edit across the whole codebase, the way they would in Next.js or SvelteKit.

$ claude "redesign the pricing page"
Works with any agent
iii. primo push

Push it back to one source of truth.

Your team opens the browser and sees the same site — editable in place, on the rendered page, with the fields your blocks declared.

Editor + renderer read the same files
Proof · the editor

The editor your clients will actually use.

In-context, on the rendered page, with the exact fields your blocks define. No separate CMS tab. No form view. No “where do I edit the homepage” support ticket on a Tuesday night.

Every field your block declared shows up as a clickable surface with a label — same model the renderer reads, no translation layer.

Why Primo exists →
okafor.coach · editor mode
For founders & operators
field · headline · text

Coaching for the hard quarters

Weekly 1:1s with someone who's shipped what you're trying to ship.

Book a session Read approach

Inside the editor — what ships today

v3.1 · Apr 2026

On-page editing

Click any text on the rendered page and type. Field chips show what you’re editing.

Drag-and-drop blocks

Reorder, add, and remove blocks on the page tree. Changes write straight to the source.

Custom page types

Define the shape of a page once. Clients create as many as they need, never breaking the model.

Custom fields

Text, rich text, image, link, number, group, repeater. The editor UI is generated from your schema.

Real-time collaboration

Multiple cursors, live presence, conflict-free edits. You and your client in the same draft.

Structured form view

For fields that aren’t visible on the page — SEO, metadata, repeaters, hidden settings. Always a click away.

Built for

Built for developers whose sites other people have to edit — freelancers, agencies, and small teams who want full code control without leaving their clients stranded.

Marketplace

Built for the real client briefs agencies actually ship.

Starters by client type — restaurants, coaches, portfolios, local services. Blocks for the sections every site needs. Fork, edit, ship. Nothing proprietary, nothing to unlearn.

12 starters · 40+ blocks

Every starter is a complete self-contained site — Svelte components and typed fields, scaffolded into your repo. No framework lock-in, no hidden runtime.

Why Primo

Every other tool makes you pick your compromise.

WordPress gives you a client-editable site but tangles content with PHP themes. Headless CMSs give you clean code but put your schema in someone else’s admin. Site builders give you drag-and-drop but you rent the result. Primo is the first one that doesn’t force the tradeoff — one source of truth, editable by both your team and your agent.

WordPress
Headless CMS
Site Builders
Primo
Where code lives portability, long-term ownership
PHP themes, coupled to WP core
Frontend, yes. Schema, no.
Inside their tool
Svelte files, your repo
Where clients edit editor surface, daily friction
/wp-admin, round-trip preview
Separate admin UI
In-tool canvas
On the rendered page
Where schema lives content model ↔ code
ACF admin, or WP tables
In their admin UI
Opaque; often inaccessible
fields.ts next to the .svelte
What agents can edit claude code, cursor, aider, any cli
Theme only; not content
Frontend only; schema locked
No file access at all
Whole site, as files
Hosting & licensing lock-in vs. ownership
Self-host, MIT
Some; most are hosted SaaS
Hosted on their platform
Self-host, MIT
Full Partial Not available
Same model since 2019 · v3.1
FAQs

The things you’re probably wondering.

Direct answers to the questions that come up every time someone first looks at Primo.

What happens to my content if Primo disappears?

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

Is this production-ready, or a side project?

+

Seven years in, v3.1. Production sites include agencies shipping client work, small commerce stores, documentation sites, and our own marketing pages. Same model since 2019 — agents are a new client of the same system, not a new product.

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

+

Payload is a headless CMS — your schema lives in their admin, content is fetched via API. TinaCMS puts a git-backed editor in front of markdown files. Sanity Studio is a React-based admin on top of their hosted content lake. Primo is none of those: the editor and the renderer both read the same Svelte files and database rows, with no API translation layer between them.

Can I use React instead of Svelte?

+

Not today. Primo is built around Svelte’s compile-time approach — it’s what lets blocks be “just files” the editor and renderer can both read directly. React support inside Primo blocks is not on the roadmap. What is on the roadmap is primo integrate <framework> — a way to layer Primo on top of an existing SvelteKit (and eventually Astro, with Next.js aspirational after that) app, where your production components stay in the framework and Primo just owns content + the editor. So you’d get a visual CMS for pages that live inside your app’s codebase, even though the blocks themselves are still Svelte.

What does a block actually look like?

+

Two files, co-located. The component renders; the schema tells the editor which fields it has.

# blocks/hero/fields.yaml
- name: headline
  label: Headline
  type: text
- name: subheadline
  label: Subheadline
  type: text
- name: cta
  label: CTA
  type: link

How do agents authenticate and push?

+

The CLI reads a PRIMO_TOKEN from your environment — you generate one per site in the admin. primo pull <host> clones the project; primo push uploads only the files that changed. Same auth an editor uses; no API surface to learn. Works over HTTPS to any Primo instance, including self-hosted.

m

I started Primo in 2019 because every client project ended the same way: I owned the code, they owned nothing, and every small edit became a dev ticket. Seven years later, the model still holds — it just happens to be the shape agents want, too.

— Matthew, founder Why Primo exists →

Start building.

Point Claude Code, Cursor, Codex, or any agent at the repo.

$ npx primo-cli init my-workspace
✓ workspace ready · server.yaml written
$ cd my-workspace
$ npx primo-cli new my-site
▸ dev server → http://localhost:3000

MIT · self-hosted · open source · free forever