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
Clone, install, run the admin and the docs, and set up the test database.
Monorepo StructureEvery app, package, plugin, and tooling folder, and how they depend on each other.
ArchitectureConfig and section loading, the field system, the submit pipeline, the API, auth, localization, schema sync, and plugins.
Adding a Field TypeThe end-to-end checklist for a new field, from config schema to admin input to column type.
TestingUnit, component, integration, and end-to-end tests.
ReleasingChangesets, versioning, and publishing to npm.
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-cmsis the product: config, sections, fields, submit, database, API, auth, CLI, plugin loader, translations, validators. It's published to npm.apps/cmsis the admin application: Next.js pages and React components that call the core through tRPC and route handlers. It's also the template thatcreate-nextjs-cmscopies 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 ofcms.config.ts. Changing them is a breaking change. - Keep the core framework-agnostic where it can be (the
corefolder avoids React), and never import server-only modules from client code. - Update the developer docs in the same pull request as the behavior change.