statamic/cli
The official command-line installer for Statamic, the Laravel-based content management system. Quickly scaffold new Statamic projects, manage installations, and streamline local setup from your terminal with simple, intuitive commands, so you can start building sites faster.
statamic/cli is not a Composer dependency you add to an app — it's a global (or ephemeral) command-line tool that runs before a project exists. That mental model drives everything below.
Install it one of two ways:
# Option A: globally, once per machine
composer global require statamic/cli
# Make sure the global bin dir is on PATH (differs by OS/composer version)
# ~/.composer/vendor/bin (composer 1 / older)
# ~/.config/composer/vendor/bin (XDG, Linux/macOS)
# %APPDATA%\Composer\vendor\bin (Windows)
# Option B: ephemeral, no global state (recommended by upstream since #111)
cpx statamic/cli new my-site
Prefer cpx on shared/CI machines and ephemeral devcontainers; prefer composer global require on a long-lived laptop where you scaffold weekly.
First commands to run:
statamic --version # confirm which binary on PATH you're actually hitting
statamic list # see the full command surface
statamic new --help # confirm flags *before* scripting anything
First use case — greenfield scaffold:
statamic new my-site
cd my-site
php please --version # sanity check the Please console boots
php artisan about # confirm Laravel + Statamic wiring
The interactive flow asks for a project name/directory, a starter kit, and (since 3.7.0, #117) a Statamic license key. Accept the defaults the first time so you see what a "vanilla" project looks like — you need that baseline before you can judge what your org conventions should override.
The second entry point is installing into an existing Laravel app:
cd existing-laravel-app
statamic install
Run that on a clean working tree, then git diff immediately. The value of statamic install is that it knows the wiring steps (config, routes, user model, migrations, composer requirements); the risk is that it edits files you care about. The diff is the documentation.
Where to look first in the scaffolded project: config/statamic/, content/, resources/views/, routes/web.php, and .env (STATAMIC_LICENSE_KEY, APP_URL). If those look right, the CLI did its job and you can stop thinking about it.
make:site scriptThe highest-leverage pattern: don't let engineers run raw statamic new. Wrap it so every project starts identically.
#!/usr/bin/env bash
# bin/new-site — org golden path
set -euo pipefail
NAME="${1:?usage: new-site <name>}"
statamic new "$NAME" --no-interaction
cd "$NAME"
# Post-scaffold conventions the CLI can't know about
composer require --dev laravel/pint friendsofphp/php-cs-fixer
cp ../templates/pint.json .
cp ../templates/.editorconfig .
cp ../templates/ci.yml .github/workflows/ci.yml # mkdir -p first
php artisan key:generate --force
git init && git add -A && git commit -m "Scaffold from statamic/cli $(statamic --version)"
This keeps the vendor tool as the inner layer and your conventions as the outer layer. When Statamic changes the installer, you inherit the fix; when your standards change, you don't fork the installer.
Rather than post-processing a blank install, publish an internal starter kit and pass it through:
statamic new my-site --starter-kit=vendor/our-starter-kit
This is where SSO packages, base layouts, deployment configs, and house style belong. Verify the exact flag name against statamic new --help on your pinned version — the starter-kit surface is the part of this tool most likely to drift.
Because the tool never appears in composer.json, the only way to make it reproducible is to install it into the image:
# Dockerfile / devcontainer
ARG STATAMIC_CLI_VERSION=3.7.0
RUN composer global require "statamic/cli:${STATAMIC_CLI_VERSION}" \
&& ln -s /root/.config/composer/vendor/bin/statamic /usr/local/bin/statamic
Now statamic --version is a fact about the image, not about the developer's laptop. Upgrades become a reviewed PR to the image, not a silent drift across the team.
- name: Scaffold
run: statamic new smoke --no-interaction
- name: Assert wiring
run: |
test -f smoke/config/statamic/system.php
test -d smoke/content/collections
grep -q '"statamic/cms"' smoke/composer.json
cd smoke && php artisan route:list | grep -q statamic
Assert against what the scaffold produced, never against what it printed. The 3.7.0 release itself (#110, #114, #118) changed human-readable output three times in one minor — that's your proof that stdout is not an interface.
statamic/cli stops being useful the moment the project directory exists. Everything after that is php please (make:collection, make:fieldset, make:user, stache:warm) and npm run dev. A common anti-pattern is expecting the CLI to manage an existing project — it doesn't; it's a birth tool, not a lifecycle tool.
composer create-project statamic/statamic my-site
Every engineer should know this one-liner. When statamic new fails on a new machine (PHP floor, network, license prompt, starter-kit auth), the fallback lets you keep working and raises a ticket separately. Without it, one opaque error blocks onboarding outright.
PHP floor is the real compatibility gate. 3.7.0 (#115) bumped minimum PHP and dependency versions. The failure doesn't appear as an obvious "your PHP is too old" message — it surfaces inside the composer create-project subprocess as a dependency-resolution error that never names the CLI as the cause. Run composer check-platform-reqs on the target machine first, and raise devcontainers/CI images/base Docker images before bumping the CLI.
The license prompt can hang in non-TTY contexts. #117 added an interactive license-key prompt. In a scripted or CI context an interactive prompt may block rather than fail fast, turning a clean error into a job timeout. Before wiring this into automation: run it under --no-interaction, and check statamic new --help for a non-interactive way to supply the key (flag or env var). If there isn't one on your pinned version, don't put statamic new in CI — scaffold from a committed template repo instead.
--no-interaction is the flag you'll actually use 90% of the time, but it also means every default gets taken silently. Review what defaults you're accepting (DB driver, starter kit, whether the CLI generated an app key) rather than assuming.
CLI version ≠ Statamic version. Confirm whether a given statamic/cli release pins the Statamic version it scaffolds or can produce a range. If it pins, then bumping the CLI silently bumps what new projects get — which may not match what your existing fleet runs. Check which statamic/cms constraint landed in the scaffolded composer.json after every CLI upgrade.
The version-check warning fires on every run and was only fixed for local checkouts in #113. Expect a network round-trip on invocation; on air-gapped or rate-limited machines budget for it, and don't be alarmed by warnings when running from a git clone of the CLI itself.
"Remember stars" (#119) writes local state. A minor thing that becomes relevant when you image machines: a preference now lives in a dotfile somewhere in the user's home. Decide whether that's acceptable in immutable/golden images, and whether you want it set centrally — check statamic --help and the config path before assuming it's stateless.
Two binaries on PATH is a classic support ticket. A stray composer global require from months ago shadowing the image-installed version produces "our flags don't exist" bugs. Debug with which -a statamic and statamic --version before anything else.
Never run statamic new inside a non-empty directory or inside an existing project. It will either refuse or, worse, interleave with your files. Scaffold into a temp dir and move if you need to.
Private or non-default starter kits need credentials. Starter-kit installation clones a repository; private ones need SSH keys or a token present at scaffold time, and the resulting error is a generic Composer/git failure rather than a clear "authenticate first". For CI, either use a public kit or pre-authenticate in the image.
Front-end assets are the most common "it installed but looks broken" cause. If the scaffold ran but the site is unstyled, the npm install && npm run build step was skipped or failed quietly. Verify public/build (or public/vendor/statamic) exists before debugging the CMS.
Assign an owner. Because this tool is invisible in composer.json and Dependabot will never flag it, it will silently go stale. Put it in the dev-image Dockerfile with a pinned version, note the current version in onboarding docs, and give one person a quarterly re-audit. That single habit is the difference between "vendor-maintained onboarding path" and "whatever version each laptop happens to have."
How can I help you explore Laravel packages today?