Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4,786 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SonicJS

GitHub stars npm downloads GitHub commit activity Discord TypeScript License: MIT

PR Tests codecov Tests npm version

The 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.

sonicjs.com

πŸ“¦ Get Started

npx create-sonicjs@latest my-app

$0 to start Β· No signup required Β· Runs anywhere SQLite runs

Sponsor Open Collective

Deploy to Cloudflare

⚠️ 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.

🐳 Self-Hosting with Docker

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.

πŸš€ Features

Edge Performance

  • ⚑ Zero Cold Starts: 0–5ms cold start vs 500–2000ms on Node.js CMSs
  • 🌍 Global by Default: 300+ edge locations β€” not one region, one continent
  • πŸš€ Sub-50ms APIs: 15–50ms API responses vs 1–4s with relations elsewhere
  • πŸ“ˆ Auto-Scaling: Cloudflare handles traffic spikes β€” no ops required

Developer Experience

  • πŸ”§ Schema-as-Code: Define your content model in TypeScript; SonicJS generates the REST API and admin UI
  • πŸ“¦ create-sonicjs CLI: From schema to global API in minutes
  • πŸ”₯ Hot Reload: Fast local development with Wrangler
  • πŸ“± Modern Stack: Hono.js, TypeScript, D1, R2, HTMX

AI-Native Content Layer

  • πŸ€– Native MCP Server: Auto-generated tools let Claude Code, Cursor, and VS Code read, create, and publish content
  • πŸ” RAG-Powered Search: Semantic search with natural-language queries β€” zero extra infra
  • πŸ›  12 Specialized Claude Code Agents: Purpose-built agents for development (View all agents)

Content Management

  • πŸ“ Rich Text Editor: TinyMCE integration with customizable toolbars
  • πŸŽ›οΈ Dynamic Fields: Text, number, date, boolean, select, media, slug, and more
  • πŸ“š Content Versioning: Complete revision history with restore β€” free, no paywall
  • ⏰ Content Scheduling: Publish/unpublish automation with date controls
  • πŸ”„ Draft β†’ Published Workflow: Role-based permissions throughout
  • πŸ’Ύ Auto-Save: Automatic content saving every 30 seconds
  • πŸ›‘οΈ XSS Protection: Comprehensive input validation and HTML escaping

No Lock-In, No Paywalls

  • 100% MIT: Every feature in the core. No Growth tier. No Enterprise gate. Ever.
  • No VC Clock: No license rug-pull. No infra lock-in.
  • Runs Anywhere: Edge-native on Cloudflare Workers, or self-host on Docker/VPS β€” anywhere SQLite runs.

πŸ“Š How SonicJS Compares

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 Included Upsold Upsold
License MIT (all features) MIT (limited) MIT (limited)

SonicJS is the only production-ready CMS built specifically for edge computing.

πŸ›  Technology Stack

Core Framework

  • Hono.js - Ultrafast web framework for Cloudflare Workers
  • TypeScript - Strict type safety throughout
  • HTMX - Enhanced HTML for dynamic interfaces

Cloudflare Services

  • D1 - SQLite database at the edge
  • R2 - Object storage for media
  • Workers - Serverless compute runtime
  • KV - Key-value storage for caching
  • Images API - Image optimization and transformation

Development Tools

  • Vitest - Fast unit testing
  • Playwright - End-to-end testing
  • Wrangler - Local development and deployment
  • Drizzle ORM - Type-safe database queries

🏁 Quick Start

For Application Developers (Using SonicJS)

# Create a new SonicJS application
npx create-sonicjs@latest my-app

cd my-app
npm run dev

# Visit http://localhost:8787

Your app includes:

  • βœ… SonicJS CMS pre-configured
  • βœ… Database migrations ready
  • βœ… Example content collections
  • βœ… Admin interface at /admin
  • βœ… Ready to deploy to Cloudflare

For Package Developers (Contributing to SonicJS)

# 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

Setting Up a Fresh Database

# 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.

Working with Database Migrations

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).

  1. Create packages/core/migrations/NNN_description.sql (use CREATE TABLE IF NOT EXISTS and INSERT OR IGNORE for idempotency)
  2. Regenerate bundle: cd packages/core && npm run generate:migrations
  3. Rebuild: npm run build:core
  4. Apply locally: cd my-sonicjs-app && wrangler d1 migrations apply DB --local

Common Commands

npm 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

πŸ“ Project Structure

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.

πŸ”§ Content Management

Creating Collections

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: [] } })

Field Types

  • string: Single-line text with validation
  • lexical: Rich text editor
  • number: Numeric input with min/max constraints
  • boolean: Checkbox with custom labels
  • datetime: Date/time picker
  • select: Dropdown with single/multi-select
  • slug: URL slug with auto-generation
  • user: User reference picker
  • media: File picker with preview

🌐 API Endpoints

Content Management

  • GET /admin/content/new?collection=id - Create new content form
  • GET /admin/content/:id/edit - Edit content form
  • POST /admin/content/ - Create content
  • PUT /admin/content/:id - Update content with versioning
  • DELETE /admin/content/:id - Delete content

Advanced Features

  • POST /admin/content/preview - Preview before publishing
  • POST /admin/content/duplicate - Duplicate content
  • GET /admin/content/:id/versions - Version history
  • POST /admin/content/:id/restore/:version - Restore version

Public API

  • GET /api/content - Get published content (paginated)
  • GET /api/collections/:collection/content - Get content by collection
  • GET /api/collections - List all collections

πŸš€ Deployment

# 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.

Environment Configuration

# 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"

πŸ§ͺ Testing

npm test                # Unit tests
npm run test:watch      # Watch mode
npm run test:e2e        # E2E tests
npm run test:e2e:ui     # E2E with UI

πŸ”Œ Plugin Development

// 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

πŸ“š Documentation

❀️ Sponsor

SonicJS is 100% open source and free forever. If you find it useful, consider sponsoring:

Sponsor on GitHub Support on Open Collective

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.

Thank You to Our Sponsors

@mmcintosh @nickgraynews

πŸ“ž Support

Community (free)

Commercial Support (for teams that need an SLA)

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 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

Sponsor this project

Used by

Contributors

Languages