Don't rent your CMS. Own it.

One npx command and the entire Next.js codebase is yours. Content lives in your GitHub, users in your Turso, media in your R2. No Statix server, no Statix bill, no Statix lock-in.

$0License / SaaS fee
100%Source code yours
GitContent database
Positioning

Every other CMS makes one trade-off.

Plotted on two axes that actually matter — how much code you own, and how deep the team features run. Three of the four live on the edges. One sits alone in the top-right.

Team featuresCode ownership
The sweet spotEnterpriseBasic
1
2
3
4
RentedOwned
  1. 1

    SaaS CMS

    Proprietary cloud · seat-priced

    Enterprise features, zero ownership.

  2. 2

    Framework CMS

    npm package · self-hosted

    Code is close — the package isn't yours.

  3. 3

    Git CMS

    File-based · admin UI

    You own the code. No team features.

  4. 4

    Statix

    Top-right

    create-statix-cms

    Full ownership. Full feature depth.

Every other CMS trades ownership for features, or features for ownership. Statix is the only point in the top-right.

Observability

The audit log we didn't write.

Every save is a commit with author metadata. Every media move is an R2 object event. Every invite acceptance is a Turso auth row. Three adapters, one activity feed, zero custom logging.

Recent Activity

System audit log

GZ
Göker Zafer
Media Uploaded
size: 801316, folder: default, contentType: image/webp10 minutes ago
AC
Alice Chen
Content Updated
a1b2c3d · collection: blog18 minutes agovia GitHub
GZ
Göker Zafer
Media Restored
legacy/hero-old.webpabout 1 hour ago
AC
Alice Chen
Content Published
f4e5d6c · collection: blogabout 2 hours agovia GitHub
ET
Ece Tuncer
Invite Accepted
role: Translatorabout 3 hours ago
AC
Alice Chen
Role Changed
ece@statix.dev → Translatorabout 5 hours ago
ET
Ece Tuncer
Content Updated
9b8c7d6 · → trabout 8 hours agovia GitHub
GZ
Göker Zafer
Content Deleted
inBlog Posts
collection: blogabout 22 hours ago

Real schema — verbatim from statix/lib/activity-feed.ts.

For editors

It's not the editor that slows writers down. It's the system behind it.

A ProseKit-powered rich text editor with a slash menu for every block. Below is the real editor surface, SLASH_ITEMS verbatim from the source.

blog / rbac-post · draft

Shipping RBAC in v2

We rolled out per-collection permissions today. The change lets teams hand translators edit access without handing them publish rights.

The rollout ships with a new role preset UI

powered by ProseKit

Per-field localization
Translate any field per locale; missing translations surface on the dashboard.
Local drafts
Close the tab by accident? Changes wait for you in localStorage.
Unsaved warnings
Navigating away with dirty state triggers a confirm prompt.
For teams

Three roles ship out of the box. You define the rest.

Owner, Admin, and Editor come wired in. Configure custom presets and per-collection permissions — the UI below is the actual role editor from the admin.

/admin/users · ece@statix.dev

Ece Tunçer

ece@statix.dev

Editor

Role preset

Permissions

Global

Collections

CollectionViewCreateEditDeletePublish
blog
pages
home
authors
User invitations
Email invites with role assignment and a token-based acceptance flow.
Audit log
Who, what, when, from which IP — filterable by user, action, or entity.
Ban system
Temporary or permanent, with expiration, reason, and notification.
For developers

Content lives in files. Media lives on R2. References are tracked.

The media library below is the real component — folders, orphan detection, hover actions. Every asset knows which content references it before you delete.

/admin/media1 unreferenced
Total 6 assets

content/blog/(4)

content/pages/(2)

R2 references counted before delete.

Total source ownership
Open any file, rewrite it, delete a whole section — npm update can't touch your code.
Type-safe config
statix.config.ts is the single source of truth, validated at startup.
Next.js 16 / React 19
App Router, Server Components, Server Actions — already wired in.
Comparison

The differences, row by row.

Categories, not brands. Every other headless CMS falls into one of three shapes — each trades something away. Contested points are covered in the FAQ.

Full source code is yours

Statix
Yes
Framework CMS
Nonpm package
SaaS CMS
NoSaaS
Git CMS
Nonpm package

Content lives in Git

Statix
Yes
Framework CMS
NoSQL
SaaS CMS
Noproprietary DB
Git CMS
Yes

Custom roles + per-collection permissions

Statix
Yes
Framework CMS
Partial
SaaS CMS
Paid
Git CMS
No

Built-in audit log

Statix
Yes
Framework CMS
Partial
SaaS CMS
Paid
Git CMS
No

User invitations + ban system

Statix
Yes
Framework CMS
Yes
SaaS CMS
Yes
Git CMS
No

Media reference tracking

Statix
Yes
Framework CMS
No
SaaS CMS
Yes
Git CMS
No

Free, unlimited users

Statix
Yes
Framework CMS
Self-host
SaaS CMS
Freemium
Git CMS
Yes

Native Next.js 16 / React 19

Statix
Yes
Framework CMS
No
SaaS CMS
Git CMS
Setup

From command to production in three steps.

One scaffold, one config, one push. Nothing hidden, nothing proprietary.

01

Scaffold

One command clones a standalone Next.js app.

$npx create-statix-cms my-cms
02

Configure

Wire up GitHub + Turso + Resend. Define collections and roles in statix.config.ts.

$vim statix.config.ts
03

Ship

Vercel, Railway, Netlify, or bare metal. Deploys anywhere Node.js runs.

$git push origin main
Install

One command. The whole codebase lands in your repo.

No npm package to depend on. No cloud account to register. Just a scaffold you own from the first commit.

terminal
$npx create-statix-cms my-cms

Not a dependency. A handoff.

You don't import statix like an npm package. After install, every file is in your repo. npm update can't change your source.

Edit, refactor, rewrite.

Editor behavior, API routes, auth flow — crack it all open. Not a fork, it's your baseline. You can't change what you don't understand — that's a feature.

Safety net

Mistakes happen. Nothing goes missing.

Dirty state prompts before you navigate away. Deletes go to trash, not the void. Restore or permanently remove on your schedule.

blog / rbac-post

You have unsaved changes

Leaving this page will discard your draft of how-we-shipped-rbac.mdx. Are you sure?

Unsaved changes warning

Navigating away while dirty prompts a confirm. Drafts survive accidental tab closes via localStorage.

/admin/trash · 3 items
how-we-shipped-rbac.mdxcontent/blog/how-we-shipped-rbac.mdx
Content
hero-old.webpuploads/landing/hero-old.webp
Media
legacy-about.mdxcontent/pages/legacy-about.mdx
Content

Restore from trash

Soft-deleted content and media stay recoverable. Restore reinstates; permanent delete commits the removal to Git.

FAQ

The objections we expect.

  • The editor updates optimistically; the UI returns instantly. Octokit commits in the background and a failure surfaces as a toast. Local caching keeps list views off the GitHub API.