A modern, TypeScript-first headless CMS built for Cloudflare's edge platform with Hono.js.
π¦ Get Started:
npx create-sonicjs@latest my-app
β οΈ 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.
- β‘ Edge-First: Built specifically for Cloudflare Workers with global performance
- π§ Developer-Centric: Configuration over UI, TypeScript-first approach
- π€ AI-Friendly: Structured codebase designed for AI-assisted development
- π Plugin System: Extensible architecture without core modifications
- π± Modern Stack: Hono.js, TypeScript, D1, R2, and HTMX
- π Rich Text Editor: TinyMCE integration with customizable toolbars
- ποΈ Dynamic Fields: Custom field types (text, number, date, boolean, select, media)
- π Content Versioning: Complete revision history with restore functionality
- β° Content Scheduling: Publish/unpublish automation with date controls
- π Workflow System: Draft β Review β Published β Archived with role-based permissions
- πΎ Auto-Save: Automatic content saving every 30 seconds
- ποΈ Live Preview: Real-time content preview before publishing
- π Content Duplication: One-click content copying and templates
- π‘οΈ XSS Protection: Comprehensive input validation and HTML escaping
- Hono.js - Ultrafast web framework for Cloudflare Workers
- TypeScript - Strict type safety throughout
- HTMX - Enhanced HTML for dynamic interfaces
- 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
- Vitest - Fast unit testing
- Playwright - End-to-end testing
- Wrangler - Local development and deployment
- Drizzle ORM - Type-safe database queries
If you want to build an application with SonicJS:
# Create a new SonicJS application
npx create-sonicjs@latest my-app
# Navigate to your app
cd my-app
# Start development server
npm run dev
# Visit http://localhost:8787Your app will be created with:
- β SonicJS CMS pre-configured
- β Database migrations ready
- β Example content collections
- β
Admin interface at
/admin - β Ready to deploy to Cloudflare
If you want to contribute to the SonicJS core package:
# Clone this repository
git clone https://github.com/lane711/sonicjs-ai.git
cd sonicjs-ai
# 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 testWhen developing the core package, migrations are located in packages/core/migrations/. Your test app will reference these migrations through the npm workspace symlink.
From your test app directory (e.g., my-sonicjs-app/):
# Check migration status (local D1 database)
wrangler d1 migrations list DB --local
# Apply pending migrations to local database
wrangler d1 migrations apply DB --local
# Apply migrations to production database
wrangler d1 migrations apply DB --remoteImportant Notes:
- The test app's
wrangler.tomlpoints to:migrations_dir = "./node_modules/@sonicjs-cms/core/migrations" - Since the core package is symlinked via npm workspaces, changes to migrations are immediately available
- After creating new migrations in
packages/core/migrations/, rebuild the core package:npm run build:core - Always apply migrations to your test database before running the dev server or tests
Creating New Migrations:
- Create a new migration file in
packages/core/migrations/following the naming pattern:NNN_description.sql - Write your migration SQL (use
CREATE TABLE IF NOT EXISTSandINSERT OR IGNOREfor idempotency) - Rebuild the core package:
npm run build:core - Apply to your test database:
cd my-sonicjs-app && wrangler d1 migrations apply DB --local
# Start development server
npm run dev
# Deploy to Cloudflare
npm run deploy
# Database operations
npm run db:migrate # Apply migrations
npm run db:studio # Open database studio
# Run tests
npm testThis is a package development monorepo for building and maintaining the SonicJS CMS npm package.
sonicjs-ai/
βββ packages/
β βββ core/ # π¦ Main CMS package (published as @sonicjs-cms/core)
β β βββ src/
β β β βββ routes/ # All route handlers (admin, API, auth)
β β β βββ templates/ # HTML templates & components
β β β βββ middleware/# Authentication & middleware
β β β βββ utils/ # Utility functions
β β β βββ db/ # Database schemas & migrations
β β βββ package.json # @sonicjs-cms/core
β βββ templates/ # Template system package
β βββ scripts/ # Build scripts & generators
β
βββ my-sonicjs-app/ # π§ͺ Test application (gitignored)
β βββ ... # Created with: npx create-sonicjs@latest
β # Used for testing the published package
β
βββ www/ # π Marketing website
βββ tests/e2e/ # End-to-end test suites
βββ drizzle/ # Database migrations
@sonicjs-cms/core npm package.
packages/core/- The main package published to npmmy-sonicjs-app/- Test installation for validating the published package (can be deleted/recreated)- No root
src/- Application code lives inpackages/core/or test apps likemy-sonicjs-app/
SonicJS uses a dynamic field system. Create collections through the admin interface or define them in the database:
-- Example: Blog Posts collection with custom fields
INSERT INTO collections (id, name, display_name, description, schema) VALUES (
'blog-posts', 'blog_posts', 'Blog Posts', 'Article content collection',
'{"type":"object","properties":{"title":{"type":"string","required":true}}}'
);
-- Add dynamic fields
INSERT INTO content_fields (collection_id, field_name, field_type, field_label, field_options) VALUES
('blog-posts', 'title', 'text', 'Title', '{"maxLength": 200, "required": true}'),
('blog-posts', 'content', 'richtext', 'Content', '{"toolbar": "full", "height": 400}'),
('blog-posts', 'excerpt', 'text', 'Excerpt', '{"maxLength": 500, "rows": 3}'),
('blog-posts', 'featured_image', 'media', 'Featured Image', '{"accept": "image/*"}'),
('blog-posts', 'publish_date', 'date', 'Publish Date', '{"defaultToday": true}'),
('blog-posts', 'is_featured', 'boolean', 'Featured Post', '{"default": false}');- text: Single-line text with validation
- richtext: WYSIWYG editor with TinyMCE
- number: Numeric input with min/max constraints
- boolean: Checkbox with custom labels
- date: Date picker with format options
- select: Dropdown with single/multi-select
- media: File picker with preview
GET /admin/content/new?collection=id- Create new content formGET /admin/content/:id/edit- Edit content formPOST /admin/content/- Create content with validationPUT /admin/content/:id- Update content with versioningDELETE /admin/content/:id- Delete content
POST /admin/content/preview- Preview content before publishingPOST /admin/content/duplicate- Duplicate existing contentGET /admin/content/:id/versions- Get version historyPOST /admin/content/:id/restore/:version- Restore specific versionGET /admin/content/:id/version/:version/preview- Preview historical version
GET /api/content- Get published content (paginated)GET /api/collections/:collection/content- Get content by collectionGET /api/collections- List all collections
After creating your app with npx create-sonicjs@latest:
# 1. Configure your Cloudflare project
# Update wrangler.toml with your project settings
# 2. Create production database
wrangler d1 create my-app-db
# 3. Apply database migrations
npm run db:migrate:prod
# 4. Deploy to Cloudflare Workers
npm run deployYour 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"# Run unit tests
npm test
# Run tests in watch mode
npm run test:watch
# Run E2E tests
npm run test:e2e
# Run E2E tests with UI
npm run test:e2e:ui- Project Plan - Development roadmap and stages
- AI Instructions - Comprehensive development guidelines
- Development Guidelines - Development workflow and principles
Create plugins for extending SonicJS functionality:
// src/plugins/my-plugin/index.ts
import { Plugin } from '@sonicjs/core'
export default {
name: 'my-plugin',
hooks: {
'content:beforeCreate': async (content) => {
// Plugin logic here
return content
}
}
} as Plugin- Global distribution via Cloudflare's network
- Sub-100ms response times worldwide
- Automatic scaling and DDoS protection
- No cold starts - instant responses
- TypeScript-first with full type safety
- Hot reload development environment
create-sonicjsCLI for instant setup- Comprehensive documentation
- Clean, structured codebase
- TypeScript types for autocomplete
- Clear conventions and patterns
- Built for AI-assisted development
MIT License - see LICENSE file for details.
We welcome contributions! Please see our contributing guidelines for more details.
Built with β€οΈ for the Cloudflare ecosystem