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", { isAdmin: 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_SEED_ADMIN_EMAIL | admin@cms.local | Email used for the seeded admin user. Only used when _user is empty. Auth is OTP-only — no password | | LOG_LEVEL | info | Pino log level (debug, info, warn, error) | | MIGRATIONS_PATH | ./migrations | Directory for migration files |

Dev mode vs production

In development, run cms migration push to sync the database schema directly from your config — no migration files. Convenient while iterating; accepts data loss.

In production, generate and commit migration files, then apply them as a pre-deploy step. cms start never auto-runs migrations.

Generate and apply migrations


          # Generate the initial migration from your config
cms migration generate initial

# Apply pending migrations
cms migration apply
        

See the CMS CLI reference for the full command list.

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 _user table, CMS creates a default admin user and logs the credentials to the console.

Previous

Introduction

Next

Configuration