Skip to content

Create a project

A Manablox instance is a small project of your own that installs the published @manablox/* packages. The manablox CLI writes it for you: the config files, a .env with generated secrets and a compose file for the services the CMS needs.

Create it

Terminal window
pnpm dlx @manablox/cli create my-cms --yes --no-admin --no-space
cd my-cms

--yes takes the defaults without asking: the local preset, Postgres, local file storage, Mailpit for mail, the public delivery API and no feature plugins. --no-admin and --no-space leave the first account and the first space to you, so Your first space can walk through both in the admin. Without them create also writes the commands that make an administrator and a space called My site. Run it without --yes to answer the questions one by one; every option is listed in Use it as a dependency.

The command installs the dependencies and runs git init. It needs Node 24 and pnpm; Docker runs the services.

Start it

Terminal window
pnpm services:up # Postgres, Valkey and Mailpit in Docker
pnpm migrate # creates the tables
pnpm dev # the management API and the admin, restarts on change

In a second terminal:

Terminal window
pnpm dev:public # the public delivery API
ServiceAddressWhat it is
Adminhttp://localhost:3000Where editors and administrators work, served by the management process
Management APIhttp://localhost:3000Everything the admin does, as an API. GraphQL at /graphql, OpenAPI at /openapi.json
Public delivery APIhttp://localhost:3100Published content of one space, for frontends
Mailpithttp://localhost:8025Catches every mail the CMS sends
Postgreslocalhost:5432The database, with the two roles described below
Valkeylocalhost:6379The cache and the job queue

One thing surprises people on a fresh instance:

  • The public delivery API waits for a space. It serves exactly one space. Until it can pin one it answers 503 and checks again every ten seconds; with exactly one space it pins that one on its own. With several, set MANABLOX_SPACE in .env to the technical name of the one to serve. Your first space creates the first.

Day to day

TaskCommand
Start the servicespnpm services:up
Stop the services (the data stays in Docker volumes)pnpm services:down
Apply migrations, after every update of the @manablox/* packagespnpm migrate
Run the management instancepnpm dev (restarts on change) or pnpm start
Run the public instancepnpm dev:public or pnpm start:public
Web Push keys for workflow notificationspnpm push-keys, then paste them into .env
Typecheck the configspnpm typecheck
Add or remove a featurepnpm exec manablox plugin install ai; see Adding and removing features later

The project’s files

FileWhat it is
manablox.config.tsThe management instance: the API and the admin at /. See The config file
manablox.public.config.tsThe hardened public delivery instance. See The public API
content-model.tsWhat every config shares: the field types and the content types defined in code
manablox.plugins.tsThe feature plugins of each instance; manablox plugin adds and removes them
compose.ymlPostgres, Valkey and Mailpit for pnpm services:up
postgres/init/Creates the database roles on the first start of Postgres
.envConnection strings and secrets, read by docker compose and by the CLI. Never commit it
.env.exampleEvery variable, commented, with the secrets blank
data/Uploads and the media cache, created on first use
README.mdThe same overview, for the preset you chose

Postgres gets two roles on its first start: manablox_owner owns the schema and runs the migrations (MIGRATION_DATABASE_URL), manablox_app is what the CMS logs in as (DATABASE_URL). See Database roles.

Content types built in the admin live in the database and need no code. Declare one in content-model.ts only when a frontend depends on its exact shape; see Content types in code.

To work on Manablox itself rather than on a project that uses it, see Contributing.

Next: Your first space.