0xCMS is an edge-native content management system that runs entirely on Cloudflare Workers. OAuth 2.1 sign-in, dual-database publishing, versioned content, private media vault — zero servers, zero cold starts.
❯ npm run deploy
Compiled Tailwind admin UI ✓
Uploaded 0xcms (2.41 sec)
D1 bindings: DB · PUBLISHED_DB
R2 vault: MEDIA_BUCKET [private]
Durable Object: PageSyncDO [realtime]
✔ Deployed to https://cms.eventuai.com
❯
// 01 — introduction
Everything a serious publishing stack needs, compiled into a single Worker. No origin servers. No databases to babysit. Trustless by default — even your media bucket is private.
Sign in with Eventuai, GitHub, or Google. Dual JWTs — 15-minute access tokens plus rotatable 7-day refresh tokens, hashed in D1 for instant revocation.
Drafts, sessions, and trash live in a private D1 store. Publishing commits an immutable snapshot to a separate published D1 — public readers never touch your admin data.
Every save mints a new page version. Roll back any page to any point in its history — your content ledger is append-only.
A Durable Object coordinates concurrent editors per page, so your team never overwrites each other's work.
Uploads land in a private R2 bucket — never public. The Worker gates every read at /media/* with on-the-fly image resizing for previews.
Extend with separate Workers over service bindings: lifecycle hooks, custom content types, fields & blocks, admin pages. No runtime installs — just bind and redeploy.
// 02 — architecture
Drafts and live content are physically separated. A public reader Worker can bind only the published database — it can't even see users, sessions, or drafts.
// 03 — get started
From clone to edge deployment in nine steps. All you need is a Cloudflare account and wrangler.
$ npm install
Two isolated stores: cms for private admin data, cms-published for live content only. Copy the printed database_id values into wrangler.toml.
$ npx wrangler d1 create cms
$ npx wrangler d1 create cms-published
Add --remote for production. Locally, npm run db:migrate applies both.
$ npx wrangler d1 migrations apply cms
$ npx wrangler d1 migrations apply cms-published
The bucket stays private; the Worker serves objects at /media/<key>. The MEDIA_BUCKET binding ships in wrangler.toml.
$ npx wrangler r2 bucket create worker-cms-media
⚠️ The JWT secret must be at least 32 characters — the Worker refuses to serve in production with a weaker key. Create .dev.vars for local dev.
# random 32-byte signing key
$ openssl rand -hex 32 | npx wrangler secret put JWT_SECRET
Pick your gateways in wrangler.toml, then add a client ID + secret per provider.
ENABLED_PROVIDERS = "eventuai,github,google"
GITHUB_CLIENT_ID = "<client-id>"
$ npx wrangler secret put GITHUB_CLIENT_SECRET
Sign in once, then promote your account. Roles are a comma-separated list.
$ npx wrangler d1 execute cms --remote \
--command "UPDATE users SET role='admin' WHERE email='[email protected]'"
$ npm run dev
# → http://localhost:8787
$ npm run deploy
// ready when you are
The live instance is running on the edge right now.
Launch 0xCMS ↗cms.eventuai.com