nextjs-cms

Contributing to nextjs-cms

How the nextjs-cms codebase is organized, how its core works, and how to make and ship changes to it.

These docs are for people working on nextjs-cms: fixing bugs, adding field types, improving the admin, or maintaining plugins. If you want to use nextjs-cms to build a CMS, read the developer docs instead.

What's here

The system in one picture

                    ┌────────────────────────── packages/nextjs-cms ───────────────────────────┐
                    │                                                                          │
 cms.config.ts ────▶│  core/config ──▶ ComputedCMSConfig (validated, defaults merged, cached)  │
 sections/*.ts ────▶│  core/factories/SectionFactory ──▶ section configs (jiti, cached, HMR)   │
                    │        │                                                                 │
                    │        ▼                                                                 │
                    │  core/sections + core/fields ──▶ Section / Field instances (.build())    │
                    │        │                                                                 │
                    │        ├──▶ core/factories/FieldFactory ──▶ client-safe form payload     │
                    │        └──▶ core/submit (NewSubmit, EditSubmit, LocaleSubmit, ...)       │
                    │                    │ validate → uniqueness → hooks → SQL → post-submit   │
                    │                    ▼                                                     │
                    │                 db (Drizzle, mysql2)                                     │
                    │                                                                          │
                    │  api/trpc (core routers + plugin routers)   auth (JWT, CSRF)             │
                    │  cli (setup, update-sections, ...)          plugins (loader, jiti)       │
                    └──────────────────────────────────────────────────────────────────────────┘
                               ▲                                         ▲
                               │ imports                                 │ imports
                    ┌──────────┴───────────┐                  ┌──────────┴───────────┐
                    │  apps/cms (admin UI) │                  │  plugins/* packages  │
                    └──────────────────────┘                  └──────────────────────┘
  • packages/nextjs-cms is the product: config, sections, fields, submit, database, API, auth, CLI, plugin loader, translations, validators. It's published to npm.
  • apps/cms is the admin application: Next.js pages and React components that call the core through tRPC and route handlers. It's also the template that create-nextjs-cms copies into new projects.
  • plugins/* are optional packages that add admin pages and routers.

Ways to contribute

  • Report a bug with the section file and config that reproduce it.
  • Fix a bug: find the owning module with the Architecture pages, add a failing test, fix it.
  • Improve the docs: every page has an "Edit this page on GitHub" link. See Writing Docs.
  • Add a feature: open an issue first for anything that changes a public API (a new field option, a config key, a section type).

Ground rules

  • Every change that affects a published package needs a changeset (pnpm changeset). CI checks for it.
  • Public APIs are the helpers developers import (textField, hasItemsSection, defineConfig, ...) and the shape of cms.config.ts. Changing them is a breaking change.
  • Keep the core framework-agnostic where it can be (the core folder avoids React), and never import server-only modules from client code.
  • Update the developer docs in the same pull request as the behavior change.