
Security News
Axios Maintainer Confirms Social Engineering Attack Behind npm Compromise
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.
@sonicjs-cms/core
Advanced tools
Core framework for SonicJS headless CMS - Edge-first, TypeScript-native CMS built for Cloudflare Workers
Core framework for SonicJS - A modern, TypeScript-first headless CMS built for Cloudflare's edge platform.
Visit sonicjs.com for full documentation and guides.
To create a new SonicJS project, use:
npx create-sonicjs my-app
This is the recommended way to get started with SonicJS. It sets up everything you need with a single command.
npm install @sonicjs-cms/core
npm install @cloudflare/workers-types hono drizzle-orm zod
npm install wrangler drizzle-kit # For development
// src/index.ts
import { createSonicJSApp } from '@sonicjs-cms/core'
import type { SonicJSConfig } from '@sonicjs-cms/core'
const config: SonicJSConfig = {
collections: {
directory: './src/collections',
autoSync: true
},
plugins: {
directory: './src/plugins',
autoLoad: false
}
}
export default createSonicJSApp(config)
// src/collections/blog-posts.collection.ts
import type { CollectionConfig } from '@sonicjs-cms/core'
export default {
name: 'blog-posts',
displayName: 'Blog Posts',
description: 'Manage your blog posts',
schema: {
type: 'object',
properties: {
title: {
type: 'string',
title: 'Title',
required: true,
maxLength: 200
},
content: {
type: 'markdown',
title: 'Content',
required: true
},
publishedAt: {
type: 'datetime',
title: 'Published Date'
},
status: {
type: 'select',
title: 'Status',
enum: ['draft', 'published', 'archived'],
default: 'draft'
}
},
required: ['title', 'content']
}
} satisfies CollectionConfig
# wrangler.toml
name = "my-sonicjs-app"
main = "src/index.ts"
compatibility_date = "2024-01-01"
[[d1_databases]]
binding = "DB"
database_name = "my-sonicjs-db"
database_id = "your-database-id"
migrations_dir = "./node_modules/@sonicjs-cms/core/migrations"
[[r2_buckets]]
binding = "BUCKET"
bucket_name = "my-sonicjs-media"
# Run migrations
wrangler d1 migrations apply DB --local
# Start dev server
wrangler dev
Visit http://localhost:8787/admin to access the admin interface.
import { createSonicJSApp } from '@sonicjs-cms/core'
import type { SonicJSConfig, SonicJSApp, Bindings, Variables } from '@sonicjs-cms/core'
import {
loadCollectionConfigs,
syncCollections,
MigrationService,
Logger,
PluginService
} from '@sonicjs-cms/core'
import {
requireAuth,
requireRole,
requirePermission,
loggingMiddleware,
cacheHeaders,
securityHeaders
} from '@sonicjs-cms/core'
import type {
CollectionConfig,
FieldConfig,
Plugin,
PluginContext,
User,
Content,
Media
} from '@sonicjs-cms/core'
import {
renderForm,
renderTable,
renderPagination,
renderAlert
} from '@sonicjs-cms/core'
import {
sanitizeInput,
TemplateRenderer,
QueryFilterBuilder,
metricsTracker
} from '@sonicjs-cms/core'
import {
createDb,
users,
collections,
content,
media
} from '@sonicjs-cms/core'
The package provides organized subpath exports:
// Services only
import { MigrationService } from '@sonicjs-cms/core/services'
// Middleware only
import { requireAuth } from '@sonicjs-cms/core/middleware'
// Types only
import type { CollectionConfig } from '@sonicjs-cms/core/types'
// Templates only
import { renderForm } from '@sonicjs-cms/core/templates'
// Utilities only
import { sanitizeInput } from '@sonicjs-cms/core/utils'
// Plugins only
import { HookSystemImpl } from '@sonicjs-cms/core/plugins'
import { Hono } from 'hono'
import { requireAuth } from '@sonicjs-cms/core/middleware'
import type { Bindings } from '@sonicjs-cms/core'
const customRoutes = new Hono<{ Bindings: Bindings }>()
customRoutes.get('/api/custom', requireAuth(), async (c) => {
const db = c.env.DB
// Your custom logic
return c.json({ message: 'Custom endpoint' })
})
// In your app config
export default createSonicJSApp({
routes: [{ path: '/custom', handler: customRoutes }]
})
import type { Plugin } from '@sonicjs-cms/core'
export default {
name: 'my-plugin',
version: '1.0.0',
description: 'My custom plugin',
async onActivate() {
console.log('Plugin activated!')
},
hooks: {
'content.beforeSave': async (content) => {
// Transform content before saving
content.metadata = { modified: new Date() }
return content
}
}
} satisfies Plugin
import { Logger, MigrationService } from '@sonicjs-cms/core'
const logger = new Logger({ category: 'custom', level: 'info' })
logger.info('Application started')
const migrationService = new MigrationService(db)
await migrationService.runAllMigrations()
@sonicjs-cms/core
├── src/
│ ├── app.ts # Application factory
│ ├── db/ # Database schemas & utilities
│ │ └── migrations-bundle.ts # Auto-generated migration bundle
│ ├── services/ # Business logic
│ ├── middleware/ # Request processing
│ ├── routes/ # HTTP handlers
│ ├── templates/ # Admin UI components
│ ├── plugins/ # Plugin system & core plugins
│ ├── types/ # TypeScript definitions
│ └── utils/ # Utility functions
├── migrations/ # Core database migrations (.sql files)
├── scripts/
│ └── generate-migrations.ts # Migration bundler script
└── dist/ # Compiled output
SonicJS uses a build-time migration bundler because Cloudflare Workers cannot access the filesystem at runtime. All migration SQL is bundled into TypeScript during the build process.
Create the SQL file in migrations/:
# Use sequential three-digit numbering
touch migrations/027_add_your_feature.sql
Write idempotent SQL:
-- migrations/027_add_your_feature.sql
CREATE TABLE IF NOT EXISTS your_table (
id TEXT PRIMARY KEY,
name TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_your_table_name ON your_table(name);
Regenerate the bundle:
npm run generate:migrations
# Or this runs automatically during: npm run build
Build the package:
npm run build
Apply to your test database:
cd ../my-sonicjs-app
wrangler d1 migrations apply DB --local
# Generate migrations bundle only
npm run generate:migrations
# Build (automatically runs generate:migrations first)
npm run build
# Type check
npm run type-check
# Run tests
npm run test
migrations/*.sql → scripts/generate-migrations.ts → src/db/migrations-bundle.ts → dist/
The generate-migrations.ts script:
.sql files from migrations/src/db/migrations-bundle.ts with embedded SQLgetMigrationSQLById() for runtime accessImportant: Always rebuild after modifying migration files. The .sql files are not used at runtime.
SonicJS follows semantic versioning:
Current Version: 2.0.0-alpha.1
# Install the new package
npm install @sonicjs-cms/core@2.0.0-alpha.1
# Run any new migrations
wrangler d1 migrations apply DB
# Test your application
npm run dev
We welcome contributions! Please see CONTRIBUTING.md.
MIT © SonicJS Team - See LICENSE for details.
Built with ❤️ for the edge | v2.0.0-alpha.1
FAQs
Core framework for SonicJS headless CMS - Edge-first, TypeScript-native CMS built for Cloudflare Workers
The npm package @sonicjs-cms/core receives a total of 631 weekly downloads. As such, @sonicjs-cms/core popularity was classified as not popular.
We found that @sonicjs-cms/core demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.