Installation
Set up a new CMS project from scratch.
Prerequisites
- Node.js 20+ (or Bun)
- Postgres 15+
- pnpm (recommended) or npm
Quick start
Install the CMS packages in your project:
pnpm add @cms/engine @cms/config
Create a cms.config.ts at your project root:
import { config, entity, text, slug, select, role } from "@cms/config";
const posts = entity("posts", {
fields: [
text("title", { required: true }),
slug("slug", { unique: true, required: true }),
select("status", { options: ["draft", "published"] }),
],
});
const admin = role("admin", { admin: true });
export default config({
entities: [posts],
roles: [admin],
});
Set up your environment:
# .env
DATABASE_URL=postgresql://user:pass@localhost:5432/cms
PORT=3000
ADMIN_UI=true
CMS_CONFIG_PATH=./cms.config.ts
Environment variables
| Variable | Default | Description |
|---|---|---|
DATABASE_URL | — | Postgres connection string (required) |
PORT | 3000 | Server port |
ADMIN_UI | true | Serve admin UI at /admin. Set false for headless-only |
CMS_CONFIG_PATH | — | Path to your cms.config.ts file |
CMS_ADMIN_EMAIL | admin@cms.local | Admin user email created on first boot |
CMS_ADMIN_PASSWORD | admin | Admin user password created on first boot |
LOG_LEVEL | info | Pino log level (debug, info, warn, error) |
MIGRATIONS_PATH | ./migrations | Directory for migration files |
NODE_ENV | — | When production, applies migration files from MIGRATIONS_PATH. Otherwise uses drizzle-kit push (see below) |
Dev mode vs production
In development (NODE_ENV is not production), the engine uses drizzle-kit push to sync the database schema directly from your config. No migration files are needed — schema changes apply automatically on restart.
In production (NODE_ENV=production), the engine applies migration files from the MIGRATIONS_PATH directory on startup. You must generate and commit these files before deploying.
Generate and run migrations
# Generate the initial migration from your config
cms migration generate
# Apply pending migrations
cms migration run
Start the server
cms dev
The API is available at http://localhost:3000/api and the admin UI at http://localhost:3000/admin.
On first boot with an empty _users table, CMS creates a default admin user and logs the credentials to the console.
Previous
Introduction
Next
Configuration