nextjs-cms

CLI

The nextjs-cms command-line tool. Set up the database, sync tables with your sections, and manage the Master admin.

The CLI ships with the nextjs-cms package. Run it from the project root through your package manager:

Terminal
pnpm nextjs-cms [global options] <command> [options]

Global options

OptionDescription
-d, --devLoad .env.development and run in development mode. Without it, the CLI loads .env and runs in production mode. Must come before the command: nextjs-cms -d update-sections.
-v, --versionPrint the installed version.
-h, --helpShow help.

Before any command runs, the CLI checks that it's inside a nextjs-cms project (a cms.config.* exists and nextjs-cms is a dependency with a matching version). If a command refuses to start, check those first.

Commands

CommandWhat it does
setupFirst-time setup: database config, system tables, Master admin.
update-sectionsSync MySQL tables with your section files. Run after every section change.
db-configSet or change the database connection.
set-master-adminSet or reset the Master admin's password.
fix-master-adminGrant the Master admin every section and plugin again.

setup

Terminal
pnpm nextjs-cms -d setup
pnpm nextjs-cms -d setup --continue

Runs, in order:

  1. db-config: asks for the connection and writes it to the env file.
  2. System tables: creates the CMS's internal tables (admins, privileges, tokens, logs, editor photos, bookkeeping) with drizzle-kit push.
  3. set-master-admin: creates the Master account.
OptionDescription
--continueSkip step 1 when the database is already configured.
Important:

If system tables already exist, setup lists them and asks before dropping and recreating them, which deletes all admins and privileges. Your section tables are not touched.

create-nextjs-cms runs nextjs-cms --dev setup for you. After it, run update-sections to create your sections' tables.

update-sections

Terminal
pnpm nextjs-cms -d update-sections

The command you'll run most. It:

  1. Loads every section from sections.path and validates it. Configuration conflicts (a reserved name, a db select pointing at a section's table...) abort the run with an explanation.
  2. Builds the tables the sections need: section tables, {table}_locales translation tables, gallery tables, destinationDb join tables, and db lookup tables.
  3. Compares them with the database and resolves each difference. Missing tables are created right away; anything that could lose data (renames, drops, type changes on existing tables) is asked about first.
  4. Creates missing unique constraints, indexes, and full-text indexes.
  5. Writes the Drizzle schema (if schemaGeneration.drizzle.enabled).
  6. Grants the Master admin access to every section (fix-master-admin).

Prompts you'll see

SituationPromptChoices
A section's table doesn't exist, and an unused table does"Is table 'articles' for section 'posts' a new table?"New table / rename an existing one (data kept)
A new field"Is field 'headline' of table 'posts' a new field?"New column / rename an existing column (data kept)
A column is no longer in your config"Field 'subtitle' exists in table 'posts' but is not in your config. What do you want to do?"Drop field / Keep field / Ask me later
A table is no longer used by any section"You are about to remove table 'old_news'. Proceed?"Yes, drop it / No, keep it / Ask me later
An existing table isn't managed yetExisting-table promptConfigure table (recommended) / Ask later

"Keep" and "ask later" leave the column or table untouched. Answering rename instead of new is how you rename a field or table without losing data.

Warning:

Changing a column's type (for example a textField to a numberField, or shrinking a maxLength) is applied with ALTER TABLE. MySQL converts or rejects existing values. Back up production data before running update-sections there.

In CI and deployments

update-sections is interactive when it needs a decision. Run it yourself against production after reviewing the changes, rather than blindly in a deploy script.

db-config

Terminal
pnpm nextjs-cms -d db-config

Prompts for host, port, username, password, and database name, tests the connection, then writes DB_HOST, DB_PORT, DB_NAME, DB_USER, and DB_PASSWORD to .env.development (with -d) or .env.production (without), replacing existing values.

set-master-admin

Terminal
pnpm nextjs-cms -d set-master-admin

Asks for a new password (twice) for the Master account, creating it if needed, and grants it every privilege. If the account exists, it asks for confirmation before resetting the password. The username is always Master.

fix-master-admin

Terminal
pnpm nextjs-cms -d fix-master-admin

Rebuilds the Master admin's privileges so it has full (CUD) access to every current section, plugin, and built-in page. update-sections already does this at the end; run it alone after restoring a database or when sections were added some other way.

Environment files

Command run withLoadsdb-config writes to
-d / --dev.env.development.env.development
no flag.env.env.production
Warning:

Without -d, the CLI reads the database credentials from .env (or from variables already set in the shell), not from .env.production. On a production server, either export the DB_* variables in the shell before running the CLI, or keep them in .env.