Primo is an MIT-licensed, agent-native visual CMS for developers — freelancers, small agencies, and small teams — who build sites for clients and need those clients to manage the content afterwards.
What it is
Primo is a content management system built around one Go binary, with PocketBase (SQLite) for storage and Svelte 5 for both the editor interface and the blocks a developer writes. The same server hosts the CMS and serves the published sites, so there are no external services and no separate frontend to wire up. Every site lives in two synchronized representations: a relational database that powers the visual editor and multi-site serving, and a folder of structured files that powers code editors, version control, and AI agents. Edit either side and both stay in sync. It has been in active development since 2019 and sits in the Content and Publishing / Content Management Systems category, with topics covering cms, static-site-generator, jamstack, pocketbase, svelte, and wordpress.
The problem it solves is the handoff after a site is built. The traditional answer to "the client needs to manage content" is the WordPress mental model — CMS plus blocks plus multi-site — but running on PHP, with themes, plugins, and hosting to maintain. Primo replaces that combination for the same job: Svelte instead of PHP, static output instead of server rendering, and one binary instead of themes, plugins, and hosting. It also replaces the split arrangement where structured content and component blocks live in a hosted CMS such as Sanity or Storyblok with a separate frontend to wire up, complete with API tokens and deployment glue.
Key capabilities
- Visual editor where non-technical editors work inside the guardrails the developer defines, so content changes do not break the site.
- Block library of reusable Svelte components shared across all sites a developer runs.
- Static output: clean, fast, SEO-friendly HTML that deploys to any static host, or can be served by Primo itself.
- Multi-site serving: one server, many sites, one dashboard, with a domain connected per site.
- Local-file workflow (beta) through the Primo CLI: primo pull yourserver.com brings the site down as local files, edits happen locally, and primo push sends changes back with the CMS updating live.
- Dual representation of every site, as a relational database and a synchronized folder of structured files, editable from either side.
- Single Go binary with PocketBase (SQLite) storage; the same server hosts the CMS and serves the published sites.
Who uses it and how
- Freelancers and small agencies who write the code for client sites and then hand content management to the client.
- Small teams running many client sites from one server and one dashboard, with a domain connected per site.
- Non-technical client editors working in the browser visual editor while the developer keeps editing files in parallel.
- Developers working with Claude Code, Cursor, or any AI agent: pull the site as local files, edit with the agent, push changes back.
- Self-hosters deploying through the one-click Railway template or on any host that runs Docker.
Getting started
The easiest route is the one-click Railway deploy template. Otherwise it runs anywhere Docker runs: docker run -d -p 8080:8080 -v primo-data:/app/pb_data ghcr.io/primocms/primo:latest, then open the server URL to create the first site.
How it compares
Primo shares the WordPress mental model of CMS plus blocks plus multi-site, but uses Svelte instead of PHP, produces static output instead of server rendering, and ships as one binary rather than themes, plugins, and hosting; against Webflow and Framer it gives clients a comparable visual editor while the developer writes real code that is self-hostable and free of vendor lock-in. It is also a static site generator in the Astro and Eleventy sense, but bundles the CMS, block library, and multi-site hosting with it, and against Sanity and Storyblok it is monolithic — no separate frontend to wire up, no API tokens, no deployment glue.
When to use it — and when not to
Self-hosting means operating the single Go binary along with its PocketBase (SQLite) storage and backing up the primo-data volume, though there is no external database, object store, or SMTP dependency to stand up. The local-file CLI workflow is labelled beta, so teams that need that path fully settled should wait, and Railway deployments must track the latest image tag rather than the main branch, which is a rolling branch build and does not advance on version releases. Teams that want a fully managed hosted CMS with vendor support, or editors who need to build layout rather than fill in guarded content, are better served elsewhere.
project readme (upstream, from github) — read inline
Primo

Primo is a CMS for developers who build sites for clients who need to manage them afterward. Your entire site stays in sync as both a database and a folder of files, so Claude Code, Cursor, and any AI agent can edit it directly. Your clients manage content visually in the browser.
In active development since 2019. Self-hosted by freelancers, agencies, and small teams.
One-click deploy:


The shape of it
One Go binary. PocketBase (SQLite) for storage. Svelte 5 for the editor UI and for the blocks you write. The same server hosts the CMS and serves your published sites — no external services, no separate frontend to wire up.
Every site lives in two synchronized representations: a relational database (powering the visual editor and multi-site serving) and a folder of structured files (powering code editors, version control, and AI agents). Edit either side, both stay in sync.
The workflow
primo pull yourserver.com # pull your site down as local files
claude # edit with Claude Code, Cursor, or any agent
primo push # push changes back — CMS updates live
Your clients keep editing content in the browser the whole time. Code and content stay in sync.
What's in the box
- Visual editor — non-technical editors work within the guardrails you define. No more "I broke the site" texts.
- Block library — reusable Svelte components, shared across all your sites.
- Static output — clean, fast, SEO-friendly HTML. Deploy to any static host, or let Primo serve it.
- Multi-site — one server, many sites, one dashboard. Connect a domain per site.
- Local-file workflow (beta) — pull/edit/push with the CLI, AI-agent compatible.
Quickstart
The easiest way to get started is Railway:

Or run it anywhere Docker runs:
docker run -d -p 8080:8080 -v primo-data:/app/pb_data ghcr.io/primocms/primo:latest
Then open your server's URL to create your first site.
Auto-updates on Railway: point your service's image at ghcr.io/primocms/primo:latest so "auto-update to the latest tag" tracks releases. If you deployed before this note and your source image is :main, switch it to :latest — :main is a rolling branch build, not a release, so it won't advance on version releases.
Next steps:
- Quickstart — key concepts
- Build your first site
- Write your first block
Who it's for
Freelancers, small agencies, and small teams who code their clients' sites and need the clients to manage content afterward — without breaking anything.
How Primo compares
- vs. WordPress — same mental model (CMS + blocks + multi-site) but built on modern tooling: Svelte instead of PHP, static output instead of server rendering, one binary instead of themes + plugins + hosting.
- vs. Webflow / Framer — your clients get a similar visual editor, but you write real code instead of using a proprietary builder. Self-hostable, no vendor lock-in.
- vs. Astro / Eleventy — Primo is a static site generator too, but bundles the CMS, block library, and multi-site hosting with it. You get the SSG workflow and the client handoff.
- vs. Sanity / Storyblok — structured content and component blocks, but monolithic: no separate frontend to wire up, no API tokens, no deployment glue.
Full comparison →
Project status
- Stable: visual CMS, block library, static output, multi-site, self-hosted deployment.
- Beta: CLI + local-file workflow (
primo pull / primo push), AI-agent compatibility.
Documentation
Community
License
MIT