SonicJS - The edge-native headless CMS for Cloudflare Workers. Sub-100ms response times, zero cold starts, TypeScript-first. Built on D1, R2, and Hono.
See the codeThe only headless CMS born on the edge. Zero cold starts. 15–50ms API responses. 300+ global locations. TypeScript-first. 100% MIT open source — every feature free, no Enterprise gate, ever.
npx create-sonicjs@latest my-app
$0 to start · No signup required · Runs anywhere SQLite runs
⚠️ Note: This repository is for developing the SonicJS core package. To build an application with SonicJS, use the command above to create a new project.
No Cloudflare account? Run SonicJS on any server with Docker and SQLite:
docker build -t sonicjs .
docker run -d --name sonicjs -p 3000:3000 \
-v $(pwd)/data:/app/data \
-e JWT_SECRET=$(openssl rand -base64 32) \
-e BETTER_AUTH_SECRET=$(openssl rand -base64 32) \
sonicjs
# Create the first admin user
docker exec sonicjs npm run reset
# → admin@sonicjs.com / sonicjs! (change after first login)
See the Self-Hosting guide for Docker Compose, Node.js, backup strategy, and production hardening.
create-sonicjs CLI: From schema to global API in minutes| SonicJS | Strapi | Payload | |
|---|---|---|---|
| Edge-native | ✅ Yes | ❌ No | ❌ No |
| Cold start | 0–5ms | 500–2000ms | 500–2000ms |
| API response | 15–50ms | 1–4s | 1–4s |
| Global locations | 300+ | 1 region | 1 region |
| Version history | Free | Paywalled | Paywalled |
| SSO / Audit logs | Free | $99+/mo | $99+/mo |
| AI / MCP / GraphQL | Included | Upsold | Upsold |
| License | MIT (all features) | MIT (limited) | MIT (limited) |
SonicJS is the only production-ready CMS built specifically for edge computing.
# Create a new SonicJS application
npx create-sonicjs@latest my-app
cd my-app
npm run dev
# Visit http://localhost:8787
Your app includes:
/admin# Clone this repository
git clone https://github.com/lane711/sonicjs.git
cd sonicjs
# Install dependencies
npm install
# Build the core package
npm run build:core
# Create a test app to validate changes
npx create-sonicjs@latest my-sonicjs-app
# Run tests
npm test
# Create a fresh D1 database for your branch (run from project root)
npm run db:reset
This creates a new D1 database named sonicjs-worktree-<branch-name>, applies all migrations, and updates wrangler.toml.
Migrations live in packages/core/migrations/. Test apps reference them via npm workspace symlink.
From your test app directory (e.g., my-sonicjs-app/):
# Check migration status
wrangler d1 migrations list DB --local
# Apply pending migrations
wrangler d1 migrations apply DB --local
# Apply to production
wrangler d1 migrations apply DB --remote
Creating New Migrations:
SonicJS bundles migrations at build time (Workers can't access the filesystem at runtime).
packages/core/migrations/NNN_description.sql (use CREATE TABLE IF NOT EXISTS and INSERT OR IGNORE for idempotency)cd packages/core && npm run generate:migrationsnpm run build:corecd my-sonicjs-app && wrangler d1 migrations apply DB --localnpm run dev # Start dev server
npm run deploy # Deploy to Cloudflare
npm run db:migrate # Apply migrations
npm run db:studio # Open database studio
npm test # Run tests
sonicjs/
├── packages/
│ ├── core/ # 📦 Main CMS package (@sonicjs-cms/core)
│ │ ├── src/
│ │ │ ├── routes/ # Route handlers (admin, API, auth)
│ │ │ ├── templates/ # HTML templates & components
│ │ │ ├── middleware/# Authentication & middleware
│ │ │ ├── utils/ # Utility functions
│ │ │ └── db/ # Database schemas & migrations
│ │ └── package.json
│ ├── templates/ # Template system package
│ └── scripts/ # Build scripts & generators
│
├── my-sonicjs-app/ # 🧪 Test application (gitignored)
│ # Created with: npx create-sonicjs@latest
│
├── www/ # 🌐 Marketing website
└── tests/e2e/ # End-to-end test suites
⚠️ This is NOT an application repository — it's for developing the @sonicjs-cms/core npm package.
Collections are TypeScript config objects registered at app startup — no database table required.
// src/collections/blog-posts.collection.ts
import type { CollectionConfig } from '@sonicjs-cms/core'
export default {
name: 'blog_post',
displayName: 'Blog Post',
slug: 'blog-posts',
description: 'Article content collection',
schema: {
type: 'object',
properties: {
title: { type: 'string', title: 'Title', required: true, maxLength: 200 },
content: { type: 'lexical', title: 'Content', required: true },
publishedAt: { type: 'datetime', title: 'Published Date' },
},
required: ['title', 'content'],
},
managed: true,
isActive: true,
} satisfies CollectionConfig
// src/index.ts — register before createSonicJSApp
import { registerCollections, createSonicJSApp } from '@sonicjs-cms/core'
import blogPostsCollection from './collections/blog-posts.collection'
registerCollections([blogPostsCollection])
export default createSonicJSApp({ plugins: { register: [] } })
GET /admin/content/new?collection=id - Create new content formGET /admin/content/:id/edit - Edit content formPOST /admin/content/ - Create contentPUT /admin/content/:id - Update content with versioningDELETE /admin/content/:id - Delete contentPOST /admin/content/preview - Preview before publishingPOST /admin/content/duplicate - Duplicate contentGET /admin/content/:id/versions - Version historyPOST /admin/content/:id/restore/:version - Restore versionGET /api/content - Get published content (paginated)GET /api/collections/:collection/content - Get content by collectionGET /api/collections - List all collectionsOpt-in plugin — add graphqlPlugin() to plugins.register:
import { graphqlPlugin, createSonicJSApp } from '@sonicjs-cms/core'
export default createSonicJSApp({
plugins: { register: [graphqlPlugin()] },
})
GET /graphql — GraphiQL playground (interactive browser IDE)POST /graphql — Execute queries and mutations (Bearer API key auth)# Query published documents
query {
documents(typeId: "blog_posts", status: "published", limit: 10) {
items { id title slug status publishedAt data }
cursor
}
}
# Create a document (requires API key)
mutation {
createDocument(typeId: "blog_posts", title: "Hello", data: {}) {
id rootId isCurrentDraft
}
}
Supports: documents, document(id) queries · createDocument, updateDocument, publishDocument, unpublishDocument, deleteDocument mutations · JSON scalar · keyset pagination.
# 1. Update wrangler.toml with your project settings
# 2. Create production database
wrangler d1 create my-app-db
# 3. Apply migrations
npm run db:migrate:prod
# 4. Deploy
npm run deploy
Your app will be live at https://your-app.workers.dev.
# wrangler.toml
name = "my-sonicjs-app"
main = "src/index.ts"
compatibility_date = "2024-01-01"
[[d1_databases]]
binding = "DB"
database_name = "my-app-db"
database_id = "your-database-id"
[[r2_buckets]]
binding = "MEDIA_BUCKET"
bucket_name = "my-app-media"
npm test # Unit tests
npm run test:watch # Watch mode
npm run test:e2e # E2E tests
npm run test:e2e:ui # E2E with UI
// src/plugins/my-plugin/index.ts
import type { Plugin, PluginContext } from '@sonicjs-cms/core'
export default {
name: 'my-plugin',
version: '1.0.0',
description: 'My custom plugin',
async activate(context: PluginContext) {
// Runs when the plugin is activated
},
async install(context: PluginContext) {
// Runs once on install — migrations, seed data, etc.
},
} satisfies Plugin
SonicJS is 100% open source and free forever. If you find it useful, consider sponsoring:
100% of sponsorship funds go to marketing — spreading the word about SonicJS to grow the community.
SonicJS is a member of Open Source Collective, a 501(c)(3) nonprofit. Donations are tax-deductible for US contributors.
Every feature stays 100% MIT and free — commercial support buys a guaranteed response time and a named contact, not features. If your company requires a support contract before adopting an open-source dependency, this is for you.
| Community | Priority Support | Enterprise | |
|---|---|---|---|
| All features (MIT, forever) | ✅ | ✅ | ✅ |
| GitHub Issues / Discord | ✅ | ✅ | ✅ |
| Guaranteed response time | — | Next business day | Same business day |
| Private support channel | — | Email + Slack | |
| Named support contact | — | — | ✅ |
| Security-issue priority triage | — | ✅ | ✅ |
| Upgrade & architecture guidance | — | ✅ | ✅ |
| License indemnification | — | — | ✅ |
| Price | Free | $499/mo | From $2,500/mo |
📄 Full terms, SLA, and procurement details: docs/commercial-support.md 📝 Request support: sonicjs.com/commercial-support
Built with ❤️ for the Cloudflare ecosystem · sonicjs.com
258 followers · starred Jan 2025
158 followers · starred Sep 2024
187 followers · starred Oct 2025
423 followers · starred Oct 2023
SonicJS - The edge-native headless CMS for Cloudflare Workers. Sub-100ms response times, zero cold starts, TypeScript-first. Built on D1, R2, and Hono.
See the codeThe only headless CMS born on the edge. Zero cold starts. 15–50ms API responses. 300+ global locations. TypeScript-first. 100% MIT open source — every feature free, no Enterprise gate, ever.
npx create-sonicjs@latest my-app
$0 to start · No signup required · Runs anywhere SQLite runs
⚠️ Note: This repository is for developing the SonicJS core package. To build an application with SonicJS, use the command above to create a new project.
No Cloudflare account? Run SonicJS on any server with Docker and SQLite:
docker build -t sonicjs .
docker run -d --name sonicjs -p 3000:3000 \
-v $(pwd)/data:/app/data \
-e JWT_SECRET=$(openssl rand -base64 32) \
-e BETTER_AUTH_SECRET=$(openssl rand -base64 32) \
sonicjs
# Create the first admin user
docker exec sonicjs npm run reset
# → admin@sonicjs.com / sonicjs! (change after first login)
See the Self-Hosting guide for Docker Compose, Node.js, backup strategy, and production hardening.
create-sonicjs CLI: From schema to global API in minutes| SonicJS | Strapi | Payload | |
|---|---|---|---|
| Edge-native | ✅ Yes | ❌ No | ❌ No |
| Cold start | 0–5ms | 500–2000ms | 500–2000ms |
| API response | 15–50ms | 1–4s | 1–4s |
| Global locations | 300+ | 1 region | 1 region |
| Version history | Free | Paywalled | Paywalled |
| SSO / Audit logs | Free | $99+/mo | $99+/mo |
| AI / MCP / GraphQL | Included | Upsold | Upsold |
| License | MIT (all features) | MIT (limited) | MIT (limited) |
SonicJS is the only production-ready CMS built specifically for edge computing.
# Create a new SonicJS application
npx create-sonicjs@latest my-app
cd my-app
npm run dev
# Visit http://localhost:8787
Your app includes:
/admin# Clone this repository
git clone https://github.com/lane711/sonicjs.git
cd sonicjs
# Install dependencies
npm install
# Build the core package
npm run build:core
# Create a test app to validate changes
npx create-sonicjs@latest my-sonicjs-app
# Run tests
npm test
# Create a fresh D1 database for your branch (run from project root)
npm run db:reset
This creates a new D1 database named sonicjs-worktree-<branch-name>, applies all migrations, and updates wrangler.toml.
Migrations live in packages/core/migrations/. Test apps reference them via npm workspace symlink.
From your test app directory (e.g., my-sonicjs-app/):
# Check migration status
wrangler d1 migrations list DB --local
# Apply pending migrations
wrangler d1 migrations apply DB --local
# Apply to production
wrangler d1 migrations apply DB --remote
Creating New Migrations:
SonicJS bundles migrations at build time (Workers can't access the filesystem at runtime).
packages/core/migrations/NNN_description.sql (use CREATE TABLE IF NOT EXISTS and INSERT OR IGNORE for idempotency)cd packages/core && npm run generate:migrationsnpm run build:corecd my-sonicjs-app && wrangler d1 migrations apply DB --localnpm run dev # Start dev server
npm run deploy # Deploy to Cloudflare
npm run db:migrate # Apply migrations
npm run db:studio # Open database studio
npm test # Run tests
sonicjs/
├── packages/
│ ├── core/ # 📦 Main CMS package (@sonicjs-cms/core)
│ │ ├── src/
│ │ │ ├── routes/ # Route handlers (admin, API, auth)
│ │ │ ├── templates/ # HTML templates & components
│ │ │ ├── middleware/# Authentication & middleware
│ │ │ ├── utils/ # Utility functions
│ │ │ └── db/ # Database schemas & migrations
│ │ └── package.json
│ ├── templates/ # Template system package
│ └── scripts/ # Build scripts & generators
│
├── my-sonicjs-app/ # 🧪 Test application (gitignored)
│ # Created with: npx create-sonicjs@latest
│
├── www/ # 🌐 Marketing website
└── tests/e2e/ # End-to-end test suites
⚠️ This is NOT an application repository — it's for developing the @sonicjs-cms/core npm package.
Collections are TypeScript config objects registered at app startup — no database table required.
// src/collections/blog-posts.collection.ts
import type { CollectionConfig } from '@sonicjs-cms/core'
export default {
name: 'blog_post',
displayName: 'Blog Post',
slug: 'blog-posts',
description: 'Article content collection',
schema: {
type: 'object',
properties: {
title: { type: 'string', title: 'Title', required: true, maxLength: 200 },
content: { type: 'lexical', title: 'Content', required: true },
publishedAt: { type: 'datetime', title: 'Published Date' },
},
required: ['title', 'content'],
},
managed: true,
isActive: true,
} satisfies CollectionConfig
// src/index.ts — register before createSonicJSApp
import { registerCollections, createSonicJSApp } from '@sonicjs-cms/core'
import blogPostsCollection from './collections/blog-posts.collection'
registerCollections([blogPostsCollection])
export default createSonicJSApp({ plugins: { register: [] } })
GET /admin/content/new?collection=id - Create new content formGET /admin/content/:id/edit - Edit content formPOST /admin/content/ - Create contentPUT /admin/content/:id - Update content with versioningDELETE /admin/content/:id - Delete contentPOST /admin/content/preview - Preview before publishingPOST /admin/content/duplicate - Duplicate contentGET /admin/content/:id/versions - Version historyPOST /admin/content/:id/restore/:version - Restore versionGET /api/content - Get published content (paginated)GET /api/collections/:collection/content - Get content by collectionGET /api/collections - List all collectionsOpt-in plugin — add graphqlPlugin() to plugins.register:
import { graphqlPlugin, createSonicJSApp } from '@sonicjs-cms/core'
export default createSonicJSApp({
plugins: { register: [graphqlPlugin()] },
})
GET /graphql — GraphiQL playground (interactive browser IDE)POST /graphql — Execute queries and mutations (Bearer API key auth)# Query published documents
query {
documents(typeId: "blog_posts", status: "published", limit: 10) {
items { id title slug status publishedAt data }
cursor
}
}
# Create a document (requires API key)
mutation {
createDocument(typeId: "blog_posts", title: "Hello", data: {}) {
id rootId isCurrentDraft
}
}
Supports: documents, document(id) queries · createDocument, updateDocument, publishDocument, unpublishDocument, deleteDocument mutations · JSON scalar · keyset pagination.
# 1. Update wrangler.toml with your project settings
# 2. Create production database
wrangler d1 create my-app-db
# 3. Apply migrations
npm run db:migrate:prod
# 4. Deploy
npm run deploy
Your app will be live at https://your-app.workers.dev.
# wrangler.toml
name = "my-sonicjs-app"
main = "src/index.ts"
compatibility_date = "2024-01-01"
[[d1_databases]]
binding = "DB"
database_name = "my-app-db"
database_id = "your-database-id"
[[r2_buckets]]
binding = "MEDIA_BUCKET"
bucket_name = "my-app-media"
npm test # Unit tests
npm run test:watch # Watch mode
npm run test:e2e # E2E tests
npm run test:e2e:ui # E2E with UI
// src/plugins/my-plugin/index.ts
import type { Plugin, PluginContext } from '@sonicjs-cms/core'
export default {
name: 'my-plugin',
version: '1.0.0',
description: 'My custom plugin',
async activate(context: PluginContext) {
// Runs when the plugin is activated
},
async install(context: PluginContext) {
// Runs once on install — migrations, seed data, etc.
},
} satisfies Plugin
SonicJS is 100% open source and free forever. If you find it useful, consider sponsoring:
100% of sponsorship funds go to marketing — spreading the word about SonicJS to grow the community.
SonicJS is a member of Open Source Collective, a 501(c)(3) nonprofit. Donations are tax-deductible for US contributors.
Every feature stays 100% MIT and free — commercial support buys a guaranteed response time and a named contact, not features. If your company requires a support contract before adopting an open-source dependency, this is for you.
| Community | Priority Support | Enterprise | |
|---|---|---|---|
| All features (MIT, forever) | ✅ | ✅ | ✅ |
| GitHub Issues / Discord | ✅ | ✅ | ✅ |
| Guaranteed response time | — | Next business day | Same business day |
| Private support channel | — | Email + Slack | |
| Named support contact | — | — | ✅ |
| Security-issue priority triage | — | ✅ | ✅ |
| Upgrade & architecture guidance | — | ✅ | ✅ |
| License indemnification | — | — | ✅ |
| Price | Free | $499/mo | From $2,500/mo |
📄 Full terms, SLA, and procurement details: docs/commercial-support.md 📝 Request support: sonicjs.com/commercial-support
Built with ❤️ for the Cloudflare ecosystem · sonicjs.com
258 followers · starred Jan 2025
158 followers · starred Sep 2024
187 followers · starred Oct 2025
423 followers · starred Oct 2023