Monorepo Structure
A map of the repository. pnpm workspaces orchestrated by Turborepo.
nextjs-cms/
├── apps/
│ ├── cms/ ← the admin app (Next.js 16), and the source of the project template
│ └── docs/ ← this documentation site
├── packages/
│ ├── nextjs-cms/ ← the core library + CLI (published: nextjs-cms)
│ ├── create-nextjs-cms/ ← the project scaffolder (published: create-nextjs-cms)
│ ├── translations/ ← extra admin UI languages (published: @nextjscms/translations)
│ └── cpanel-api/ ← shared cPanel client for the cPanel plugins
├── plugins/
│ ├── plugin-cache-revalidation/
│ ├── plugin-cpanel-dashboard/
│ ├── plugin-cpanel-emails/
│ └── plugin-google-analytics/
├── tooling/ ← shared ESLint, Prettier, Tailwind, TypeScript configs
├── testing/ ← integration-test database (docker-compose) and global setup
├── .changeset/ ← pending changesets
├── turbo.json
├── pnpm-workspace.yaml ← workspaces + dependency catalog
└── vitest.config.ts ← unit / component / integration projectspackages/nextjs-cms
The heart of the project. Compiled with tsc to dist/, exposed through subpath exports (nextjs-cms/core/fields, nextjs-cms/api/server, ...).
| Folder | Responsibility | Read |
|---|---|---|
src/core/config | Load, validate, merge, cache, and watch cms.config.* | Config Loading |
src/core/factories | SectionFactory (load section files), FieldFactory (build form payloads) | Section Loading |
src/core/sections | simpleSection, hasItemsSection, categorySection and their classes | Section Loading |
src/core/fields | One file per field type: config schema, helper, class | Field System |
src/core/submit | Create/edit/locale submission classes | Submit Pipeline |
src/core/helpers | Conditional rules, watermark, backgrounds, entityKind/is() | |
src/core/localization | resolveLocale | Localization Internals |
src/core/security | escapeHTML, rich-text sanitizer | |
src/core/db | MysqlTableChecker (introspection) | Schema Sync |
src/api | tRPC routers, server actions, React client | API Layer |
src/auth | JWT, refresh tokens, CSRF, useSession | Authentication |
src/db | Drizzle client and the CMS system schema | |
src/cli | nextjs-cms commands and the schema generator | Schema Sync |
src/plugins | Plugin types, definePlugin, loader, client context | Plugin Loader |
src/translations | Base English dictionary, getString, language utils | Localization Internals |
src/validators | Zod schemas used by the admin form for client-side validation | Field System |
src/logging | Audit log events (recordLog) |
apps/cms
The admin application and the reference project. Notable folders:
| Path | What |
|---|---|
app/(auth) | Login |
app/(rootLayout) | Authenticated pages: browse, new, edit, section (simple), categorized, admins, log, settings, dashboard, and (plugins)/[...slug] |
app/api | Route handlers: submit/section/*, photo, video, document, editor/photo, auth/*, trpc/[trpc] |
app/_trpc | createTRPCRouter() instance (api, HydrateClient) |
components/form | The generic form and one input component per field type (inputs/*-form-input.tsx) |
sections/ | Sample sections, including __TESTS__ sections used by Playwright |
playwright/ | E2E output |
packages/create-nextjs-cms/templates/ is generated from apps/cms by the scaffolder's prebuild script (scripts/build.ts). Don't edit it; change apps/cms instead.
packages/create-nextjs-cms
The create-nextjs-cms CLI: prompts (name, sample sections, database, git), copies the template, generates secrets, installs dependencies, and runs nextjs-cms --dev setup. Sample sections are written by src/lib/section-creators.ts.
packages/translations
Additional admin dictionaries (@nextjscms/translations/ar, ...). The English base dictionary lives in core at nextjs-cms/translations/base/en.
plugins/*
Each plugin is a package named @nextjscms/plugin-<slug> with define.ts (descriptor), index.ts (createPlugin), router.ts, server.tsx, and client/. See Plugin Loader and the developer guide Building Plugins.
tooling/
Shared configs consumed as workspace packages: ESLint, Prettier (@lzcms/prettier-config), Tailwind, and TypeScript base configs.
Dependency direction
apps/cms ─────▶ nextjs-cms ◀───── plugins/*
│ ▲ │
└──▶ @nextjscms/translations └──▶ @nextjscms/cpanel-api
create-nextjs-cms ──(copies)──▶ apps/cms templatenextjs-cms never imports from apps/ or plugins/.