Configuration

The cms.config.ts file is the single entry point for all CMS configuration.

Everything is configured through a single cms.config.ts file. The engine loads this file at startup and uses it to build the database schema, register API routes, set up permissions, and configure the admin UI.

Config structure


          import { config, entity, role, text, slug, select, relation, object, blocks } from "@cms/config";

export default config({
  // Locales for i18n (optional)
  locales: ["en", "pt", "fr"],
  defaultLocale: "en",

  // CORS origins for external frontends (optional)
  cors: {
    origins: ["https://example.com"],
  },

  // Media storage adapter (optional, defaults to local)
  storage: {
    adapter: "local",  // or "s3", "r2"
    path: "./uploads",  // upload directory (default: "./uploads")
  },

  // Your content entities
  entities: [posts, pages, authors],

  // Roles and permissions
  roles: [admin, editor, publicRole],
});
        

Built-in entities

CMS automatically registers two built-in entities that you don’t need to define:

_users


          // Auto-registered with these fields:
// - email (text, unique, required)
// - name (text)
// - password (text, hidden) — bcrypt hash
// - role (text, required)
// Plus automatic: id, createdAt, updatedAt
        

_media


          // Auto-registered with these fields:
// - filename (text, required)
// - mimeType (text, required)
// - size (number)
// - width (number)
// - height (number)
// - alt (text)
// - url (text, required)
// Plus automatic: id, createdAt, updatedAt
        

Automatic fields

Every entity automatically gets:

  • id — UUID primary key
  • createdAt — timestamp, set on insert
  • updatedAt — timestamp, set on insert and update

You never define these — they’re always present.

Admin UI configuration

The admin UI is configured through the admin key:


          export default config({
  admin: {
    logo: "/logo.svg",
    title: "My CMS",
    theme: {
      primary: "oklch(0.7 0.15 250)",
    },
    css: "./admin.css",
    sidebar: [
      { label: "Analytics", path: "/analytics", icon: "ChartBar" },
    ],
    dashboard: [() => import("./RevenueWidget")],
    routes: [
      { path: "/analytics", component: () => import("./AnalyticsDashboard") },
    ],
    components: {
      field: {
        color: () => import("./ColorPicker"),
        "posts.hero": () => import("./HeroEditor"),
      },
      list: {
        products: () => import("./ProductGrid"),
      },
    },
  },
  // ...
});
        

See Admin Extensibility for the full guide.

Previous

Installation

Next

Fields