The manablox command
manablox is the command line tool that creates, updates and starts your CMS. This page lists every command and every option. For a guided first run, start with Create your CMS instead.
How to run it
Section titled “How to run it”There are two ways, depending on whether you already have a project:
- To create something new, run it straight from npm without installing it:
pnpm dlx @manablox/cli create my-cmsorpnpm dlx @manablox/cli frontend my-site(npx @manablox/cli ...works the same). - Inside a project made by
manablox create, the command is already installed. Use the scripts inpackage.json(pnpm dev,pnpm migrate) orpnpm exec manablox <command>for everything else.
Run the commands in your project folder: that is where manablox looks for the config file and .env.
| Command | What it does |
|---|---|
manablox create [dir] | Creates a new CMS project in a folder |
manablox frontend [dir] | Creates a starter website for a space |
manablox start | Starts the CMS |
manablox migrate | Brings the database up to date |
manablox backup <file> | Copies a SQLite database into a file while the CMS runs |
manablox sync | Writes the workflows, webhooks, credentials and templates declared in code into the database |
manablox push-keys | Prints a key pair for push notifications |
Options in general
Section titled “Options in general”- An option with a value can be written as
--port 3000or--port=3000. - A yes or no option has two forms:
--installand--no-install. - An option the command does not know stops it with
manablox: unknown option '--xyz'; see manablox --help. A typo never goes unnoticed. -hor--helpprints the built-in help text for all commands.manabloxwithout a command also prints the help text, but ends with an error code.
The config file and .env
Section titled “The config file and .env”start, migrate, backup and sync read your configuration. They look for it like this:
- First they load the file
.envfrom the folder you run the command in, if it exists. A variable that is already set in your terminal wins over the value in.env. - Then they load the config file: the one given with
--config <file>(relative to the current folder), or else the first ofmanablox.config.ts,manablox.config.mts,manablox.config.jsormanablox.config.mjsin the current folder.
The config file must export its configuration as the default export (export default defineConfig({ ... })); a named export called config works too.
If no config file is found, you see no manablox.config.ts in <folder>; create one or pass --config <file>, or config file not found: <path> when the file given with --config does not exist. Both usually mean you are not in your project folder.
create, frontend and push-keys read neither file.
manablox start
Section titled “manablox start”Starts the CMS and keeps running until you stop it with Ctrl+C.
pnpm exec manablox startpnpm exec manablox start --watchpnpm exec manablox start --config manablox.public.config.tsIn a project made by manablox create, the scripts do this for you: pnpm dev runs manablox start --watch, pnpm start runs manablox start, and pnpm dev:public and pnpm start:public do the same with --config manablox.public.config.ts for the public API.
| Option | Default | Meaning |
|---|---|---|
--config <file> | manablox.config.ts | The config file to load |
--watch | off | Restart whenever the config file or any file it imports changes (for example content-model.ts or your plugins) |
--mode <mode> | from the config, else management | management runs the admin and the management API, public runs the read-only public API. Anything else stops with an error |
--port <port> | from the config | The port to listen on |
--host <host> | from the config | The network address to listen on, for example 0.0.0.0 for all |
When the CMS is ready, the log shows manablox listening (or manablox public api listening) with its address. If the config is not valid, it prints manablox: the configuration is invalid followed by one line per problem, and stops.
manablox migrate
Section titled “manablox migrate”Creates the database tables, or brings them up to date after an update of Manablox. Run it once for a new database and after every update. It is safe to run it again: it only does what is missing.
pnpm migrate| Option | Default | Meaning |
|---|---|---|
--config <file> | manablox.config.ts | The config file whose database address is used |
When it is done, it prints manablox: migrations applied. If the config has no database address, it stops with manablox: database.url is not set in the config.
In a docker project, the migrate service does this automatically before the CMS starts. To run it by hand there: docker compose run --rm migrate.
manablox backup
Section titled “manablox backup”Writes a consistent copy of the database into a new file, while the CMS keeps running. It works for SQLite (a database that is a single file, see The database) only; for Postgres it stops with an error, use pg_dump there. It never overwrites a file: if the file exists, it stops. Missing folders are created.
pnpm exec manablox backup backups/2026-01-31.db| Option | Default | Meaning |
|---|---|---|
--config <file> | manablox.config.ts | The config file that holds the database address |
When it is done, it prints manablox: database copied to <file>. The messages it can stop with:
| Message | Cause |
|---|---|
backup needs a file to write, e.g. manablox backup backups/cms.db | No file name was given |
<file> exists; backup never overwrites | The file is already there. Pick a new name |
backup copies SQLite databases; back Postgres up with pg_dump | The project uses Postgres |
To restore, stop the CMS, replace the database file with the copy (and delete the -wal and -shm files next to it), then start the CMS again. In a docker project, ./scripts/backup.sh and ./scripts/restore.sh do this for you; see Backups.
manablox sync
Section titled “manablox sync”Your config and plugins can declare workflows, webhook endpoints, credential slots and content templates in code (see Workflows and webhooks in code). sync writes them into every space they target, so they appear in the admin.
pnpm exec manablox sync --dry-runpnpm exec manablox syncpnpm exec manablox sync --space blog| Option | Default | Meaning |
|---|---|---|
--config <file> | manablox.config.ts | The config file to load |
--space <name> | all spaces | Only this space, by its technical name. An unknown name stops with no space with the machine name '<name>' |
--dry-run | off | Only show what would change, write nothing |
--prune | off | Delete what is no longer declared. Without it, such things are only switched off |
It prints one line per change, and a count of the unchanged ones at the end. The sign at the start of each line says what happened:
| Sign | Meaning |
|---|---|
+ | created |
~ | updated |
- | deleted (only with --prune) |
o | switched off, or handed back to the editors |
! | skipped, with the reason after it |
If there is nothing to do, it says nothing to do.
manablox push-keys
Section titled “manablox push-keys”Prints a new key pair for web push notifications (the kind a browser shows even when the admin is closed).
pnpm push-keysIt prints four lines, ready to paste into .env: PUSH_VAPID_PUBLIC_KEY, PUSH_VAPID_PRIVATE_KEY and an example PUSH_VAPID_SUBJECT (change the address to yours). Create the keys once and keep them: new keys break the subscriptions browsers already have. It has no options. In a docker project, run it as docker compose run --rm --no-deps api push-keys.
manablox create [dir]
Section titled “manablox create [dir]”Writes a complete, runnable CMS project into a new folder: config files, a .env with freshly generated secrets, and a Docker Compose file. See Create your CMS for a walk-through and A tour of your project for the files it writes.
pnpm dlx @manablox/cli create my-cmspnpm dlx @manablox/cli create my-cms --yespnpm dlx @manablox/cli create my-cms --preset docker --proxy caddy --admin-domain cms.example.com --public-domain content.example.com --acme-email you@example.comEvery option you do not give is asked in the terminal. With --yes, or when there is no terminal (for example in a script), nothing is asked and the defaults are used.
The questions
Section titled “The questions”They come in this order. Questions that do not apply to your earlier answers are left out.
| Question | Asked when | Default |
|---|---|---|
| Where should the instance be created? | No folder was given | my-cms |
| Project name | Always | The folder name |
| Which database? | No --database given | Postgres |
| How will this instance run? | No --preset or --proxy given, or --preset docker without --proxy | Local development (Docker behind Caddy with --preset docker) |
| Add a public delivery instance? | Always | Yes |
| Domain of the admin and management API | Docker with Caddy or nginx | cms.example.com |
| Domain of the public delivery API | Docker with Caddy or nginx, with the public API | content.example.com |
| Email for TLS certificate notices | Docker with Caddy | ops@example.com |
| Port of the admin and management API | Local, or Docker with ports published | 3000 |
| Port of the public delivery API | Same, with the public API | 3100 |
| Port to publish Postgres on | Local, with Postgres | 5432 |
| Port to publish Valkey on | Local | 6379 |
| Where do uploads live? | Always | On disk |
| How does this instance send mail? | Always | Mailpit for local, No mail for Docker |
| Install dependencies now with pnpm? | Always | Yes |
| Initialise a git repository? | Always | Yes |
| Start Postgres and Valkey, migrate and run pnpm dev once everything is installed? (local; with SQLite it names only Valkey) or Build and start the Docker stack once everything is installed? (docker) | When installing | No |
The answers to “Which database?” are Postgres and SQLite. The answers to “How will this instance run?” are Local development, Docker behind Caddy, Docker behind nginx, and Docker, ports published.
Options
Section titled “Options”| Option | Default | Meaning |
|---|---|---|
[dir] or --dir <dir> | asked, else my-cms | The folder to create. It must be empty or not exist yet |
--name <name> | the folder name | The name in package.json and of the Docker Compose project. Lowercase letters, digits, -, _ and . |
--preset <preset> | local | local: Docker runs only Postgres and Valkey (with SQLite only Valkey), the CMS runs on your computer. docker: every part in containers, for a server |
--proxy <proxy> | caddy | Docker only; giving it without --preset picks docker. caddy: a web server with automatic HTTPS certificates. nginx: a web server with certificates you provide. none: no web server, the ports are published for one you run yourself |
--database <database> | postgres | postgres: a Postgres server, run by Docker in both presets; the public API connects with its own read-only database user. sqlite: the whole database is one file (data/manablox.db, or the database volume in the docker preset), so no database server runs at all. SQLite allows one writer, so run only one management instance. The backup scripts use manablox backup |
--public / --no-public | --public | Add the separate, read-only public API for your websites, or leave it out |
--admin-domain <host> | cms.example.com | Caddy and nginx: the domain of the admin. A prefix http:// means no HTTPS, for a trial |
--public-domain <host> | content.example.com | Caddy and nginx: the domain of the public API, same rules |
--acme-email <email> | ops@example.com | Caddy: where certificate notices are sent |
--admin-port <port> | 3000 | Without a web server: the port of the admin and the management API |
--public-port <port> | 3100 | Without a web server: the port of the public API |
--postgres-port <port> | 5432 | Local with Postgres: the port Postgres is reachable on from your computer |
--valkey-port <port> | 6379 | Local: the port Valkey is reachable on |
--storage <driver> | local | local: uploads are saved on disk. s3: in an S3-compatible bucket, whose keys go into .env |
--mail <driver> | mailpit (local), none (docker) | smtp, mailpit, gmail, microsoft, resend, sendgrid, postmark, mailgun or none. See Sending email |
--manablox-version <range> | the version of this command | The version range of the @manablox/* packages. Never asked |
--install / --no-install | --install | Run pnpm install after writing the files |
--git / --no-git | --git | Run git init after writing the files |
--start / --no-start | --no-start | Start right away. Local: starts Postgres (not with SQLite) and Valkey, migrates and runs pnpm dev. Docker: builds the image and starts every container |
--force | off | Write into a folder that is not empty |
--yes | off | Ask nothing and use the defaults for everything not given |
Checks and messages
Section titled “Checks and messages”Values are checked before anything is written. In the questions, a wrong answer shows the problem and asks again; on the command line it stops the command.
| Message | Cause |
|---|---|
--name '...' is not a valid package name | Uppercase letters, spaces or other characters in the name |
--preset must be one of local, docker, not '...' | A value that is not in the list (the same for --proxy, --database, --storage and --mail) |
--admin-port '...' is not a port | A port must be a whole number from 1 to 65535 |
--admin-domain '...' is not a host name | A domain like cms.example.com, optionally with http:// in front |
--acme-email '...' is not an email address | Not an email address |
--start needs the dependencies installed; drop --no-install | --start and --no-install together |
... is not empty; pass --force to write into it anyway | The folder already has files in it |
If pnpm install, git init or a start step fails, the files stay written and the command tells you what to run yourself. At the end it prints “Next steps” with the commands for your setup. With --start on a local project, it hands over to pnpm dev in the same terminal.
manablox frontend [dir]
Section titled “manablox frontend [dir]”Writes a starter website that reads your content from the public API: it finds pages by their web address, draws blocks with one component each, and has a /preview page for the admin’s visual editor. See The starter website for what you get.
pnpm dlx @manablox/cli frontend my-sitepnpm dlx @manablox/cli frontend my-site --framework astro --yespnpm dlx @manablox/cli frontend my-site --url https://content.example.com --editor-origin https://cms.example.comAs with create, missing options are asked, and --yes or a missing terminal uses the defaults.
The questions
Section titled “The questions”| Question | Asked when | Default |
|---|---|---|
| What should the frontend be built with? | No --framework given | Astro |
| Where should the frontend be created? | No folder given | my-site |
| Project name | Always | The folder name |
| URL of the delivery API | Always | http://localhost:3100 |
| The admin’s origin, for the visual editor’s preview channel | Always | http://localhost:3000 |
| Write components for a space’s content and block types? | No --model or related option given | Yes, from the management API |
| URL of the management API, API key | Components from the management API | http://localhost:3000 |
| Which space should the components be written for? | The key can read several spaces | the first |
| Which types should get a component? | Components are written | All types |
| Space id | Always | empty, or the space picked above |
| Port of the dev server | Always | depends on the framework |
| Install dependencies now with pnpm? | Always | Yes |
| Initialise a git repository? | Always | Yes |
If the content model cannot be read (wrong address, wrong key), you can try again or go on without it; you then get an example “teaser” block instead. For the “delivery API” answer, the public API must be running; for the management API you need an API key from Settings > API keys in the admin (see API keys).
Options
Section titled “Options”| Option | Default | Meaning |
|---|---|---|
[dir] or --dir <dir> | asked, else my-site | The folder to create |
--framework <name> | astro | plain (Vite and TypeScript, rendered in the browser), astro (Astro, rendered on the server), react-ssr (React, rendered on the server), vue-ssr (Vue, rendered on the server) |
--name <name> | the folder name | The name in package.json |
--url <url> | http://localhost:3100 | The public API the website reads from |
--editor-origin <url> | http://localhost:3000 | The address of the admin. The preview page only accepts messages from there |
--space-id <id> | empty | Leave empty for the public API, which serves exactly one space |
--port <port> | 3003 plain, 3005 astro, 3006 vue-ssr, 3007 react-ssr | The port of the website’s dev server |
--model <source> | asked; none with --yes or without a terminal | Where to read your content types from: management (with an API key), delivery (the public API at --url, no key) or none (just the example block) |
--api-url <url> | http://localhost:3000 | The management API, for --model management |
--api-key <key> | none | An API key that may read the space. Implies --model management; required for it with --yes or without a terminal |
--space <name> | the only one | The space by technical name or id. Needed when the key can read several spaces |
--types <list> | all | The content and block types to write components for, as all or a comma-separated list like page,teaser |
--manablox-version <range> | the version of this command | The version range of the @manablox/* packages |
--install / --no-install | --install | Run pnpm install afterwards |
--git / --no-git | --git | Run git init afterwards |
--force | off | Write into a folder that is not empty |
--yes | off | Ask nothing and use the defaults |
URLs must start with http:// or https://; a slash at the end is removed. Giving --api-key, --api-url or --space without --model means management; giving only --types means delivery.
The addresses end up in the website’s .env (MANABLOX_URL, MANABLOX_ADMIN_ORIGIN, MANABLOX_SPACE_ID, with a VITE_ prefix for plain), where you can change them later.
Exit codes
Section titled “Exit codes”When a command ends, it reports a number to the terminal or script that ran it. 0 means success.
| Code | Meaning |
|---|---|
0 | Success, or the help text was asked for |
1 | Something went wrong: an unknown command or option, a wrong value, an invalid config, or an error while running. The message starts with manablox: |
2 | Only sync --dry-run: there is something to change. A deploy script can stop on this |
130 | create or frontend was cancelled with Ctrl+C during the questions. It prints manablox: cancelled, nothing was written |
create --start on a local project ends with the exit code of pnpm dev, which it runs at the end.