Skip to content

CLI

The civitai CLI (Go, repo civitai/cli) is the canonical tool for authoring Civitai Apps. Its app command group scaffolds a correct project, validates it against the platform contract, and packages + submits it for review.

This replaces the deprecated @civitai/blocks-cli

The old npm @civitai/blocks-cli (with init / dev / deploy) is deprecated. Install the civitai binary instead — its authoring commands below are the source of truth.

Install

Pick whichever fits — npm is the most convenient if you already have Node (App authors usually do); the others need no Node toolchain:

bash
# npm (a thin wrapper that downloads the matching prebuilt binary)
npm install -g @civitai/cli
# or, without installing:
npx @civitai/cli --help

# Homebrew (macOS / Linux)
brew install civitai/tap/civitai

# Go install (from source, Go 1.25+)
go install github.com/civitai/cli/cmd/civitai@latest

Prebuilt binaries for linux/macOS/windows × amd64/arm64 are on the GitHub Releases page. Verify with civitai version.

Authenticate

Most app commands that talk to the platform need a stored credential:

bash
civitai login                    # browser device login
# or a full-scope personal API key (needed for real Buzz-spend in dev:live):
civitai login --token <key>      # create the key at civitai.com/user/account

The App lifecycle

The authoring flow is create → validate → submit, then review on civitai.com. The platform rebuilds your app from source — there is no client-side deploy.

bash
civitai app create my-app        # scaffold a ready-to-build App
cd my-app
npm install && npm run dev:harness   # iterate locally against the mock host
civitai app validate             # local pre-check of block.manifest.json
civitai app submit               # package the SOURCE tree + submit for review
civitai app status               # track review / deploy state

civitai app submit enters your app into moderator review — it is not published immediately. On approval the platform builds + deploys it and serves it at https://<blockId>.civit.ai/.

The commands and flags below are generated from the civitai app --help command tree.

civitai app create[name] [dir]

Create a ready-to-build App (batteries-included, SDK money-path)

FlagDescriptionDefault
--dir stringoutput directory (default ./<slug>)
--from stringfork from an existing published app slug (not yet wired)
--name stringdisplay name (default derived from the name argument)
-t, --template stringproject template: static | page-vite | page-moneypage-money
-y, --yesnon-interactive: never prompt (use flags/defaults; fail if a name is missing)

civitai app init[name] [dir]

Scaffold a ready-to-build App project

FlagDescriptionDefault
--dir stringoutput directory (default ./<slug>)
--from stringfork from an existing published app slug (not yet wired)
--name stringdisplay name (default derived from the name argument)
-t, --template stringproject template: static | page-vite | page-moneystatic
-y, --yesnon-interactive: never prompt (use flags/defaults; fail if a name is missing)

civitai app validate[dir]

Validate block.manifest.json against the App schema

FlagDescriptionDefault
--jsonemit the validation result as JSON (scriptable)
--stricttreat warnings as failures (non-zero exit)

civitai app submit[dir]

Package and submit an App for review

FlagDescriptionDefault
-o, --out stringoutput .zip path (default: <blockId>-<version>.zip)
--package-onlyonly write the .zip; do not attempt submission
--skip-validateskip manifest validation before packaging
-y, --yesskip the confirmation prompt and submit (for scripts/CI)

civitai app status[blockId]

Check the review/deploy status of your App submissions

FlagDescriptionDefault
--id stringlook up a single submission by publish-request id (pubreq_...)
--jsonemit raw JSON (scriptable)

civitai app withdraw[pubreq-id]

Withdraw your own pending App submission

FlagDescriptionDefault
--id stringthe publish-request id to withdraw (pubreq_...)
-y, --yesaccepted for symmetry with 'app submit' (withdraw is non-interactive; no-op)

civitai app listing

Manage your App store-listing media (icon, cover, screenshots)

civitai app listing set-icon<file>

Set the listing icon (a square-ish image)

FlagDescriptionDefault
--changelog stringchangelog for the moderator review (used only when the listing is already live)
--dir stringapp directory holding block.manifest.json (when --slug is not given).
--slug stringapp slug (defaults to block.manifest.json's blockId)
-y, --yesskip the live-listing revision confirmation

civitai app listing set-cover<file>

Set the listing cover (a landscape hero image)

FlagDescriptionDefault
--changelog stringchangelog for the moderator review (used only when the listing is already live)
--dir stringapp directory holding block.manifest.json (when --slug is not given).
--slug stringapp slug (defaults to block.manifest.json's blockId)
-y, --yesskip the live-listing revision confirmation

civitai app listing add-screenshot<file>

Add a screenshot (up to 8) with an optional caption

FlagDescriptionDefault
--caption stringoptional one-line caption for the screenshot
--changelog stringchangelog for the moderator review (used only when the listing is already live)
--dir stringapp directory holding block.manifest.json (when --slug is not given).
--slug stringapp slug (defaults to block.manifest.json's blockId)
-y, --yesskip the live-listing revision confirmation

civitai app listing rm-screenshot<screenshotId>

Remove a screenshot by its id (see `app listing status`)

FlagDescriptionDefault
--dir stringapp directory holding block.manifest.json (when --slug is not given).
--slug stringapp slug (defaults to block.manifest.json's blockId)

civitai app listing reorder<screenshotId...>

Reorder screenshots (pass ALL current screenshot ids in the new order)

FlagDescriptionDefault
--dir stringapp directory holding block.manifest.json (when --slug is not given).
--slug stringapp slug (defaults to block.manifest.json's blockId)

civitai app listing status

Show attached media and what's missing vs the publish floor

FlagDescriptionDefault
--dir stringapp directory holding block.manifest.json (when --slug is not given).
--slug stringapp slug (defaults to block.manifest.json's blockId)

civitai app list

Discover published Apps in the store (GET /api/v1/apps)

FlagDescriptionDefault
--category stringfilter by marketplace category (generation, games, utility, discovery, moderation, analytics, other)
--cursor stringpagination cursor from a previous response
--jsonprint the raw API JSON response (for scripting)
--kind stringfilter by kind (all, onsite, offsite)
--limit intresults per page (1-50)
--sort stringsort order (top-rated, popular, newest, name)

civitai app view<slug>

Show one App's detail (GET /api/v1/apps/{slug})

FlagDescriptionDefault
--jsonprint the raw API JSON response (for scripting)

civitai app dev-token<slug>invite-only

Mint a short-lived dev block token for `npm run dev:live`

FlagDescriptionDefault
--envprint VITE_LIVE_BLOCK_TOKEN=<token> (paste-ready into .env.development.local)

civitai app dev-tunnel[blockId]invite-only

Preview your LOCAL dev server inside the real Civitai host via a hardened tunnel

FlagDescriptionDefault
--block stringthe blockId (app slug) to tunnel (or pass it positionally; defaults to the blockId in block.manifest.json in the CWD)
--idle-timeout durationtear the tunnel down after this much inactivity30m0s
--local-host localhosthost your local dev server is bound to. Default localhost (loopback) — the scaffold's `dev:tunnel` binds localhost, so most users need nothing. Set this for a dev server NOT on the CLI's loopback: a container/pod (e.g. --local-host 10.42.0.100), a VM, or a specific bound interfacelocalhost
--no-waitskip the readiness wait and print the URL immediately (it may 404/NXDOMAIN for ~1–2 min while DNS/route propagate)
--port intlocal dev-server port to tunnel (matches the scaffold's dev:tunnel)5186
--ready-timeout durationcap the wait for the public host to start serving (0 = wait indefinitely until ready or Ctrl-C; a positive value warns + prints the URL anyway on expiry)
--tunnel-endpoint stringsish SSH endpoint host:port (default sish.civitai.com:2224, or $CIVITAI_DEV_TUNNEL_ENDPOINT)

civitai app pull[dir]

Clone or sync your app's repository from Civitai

FlagDescriptionDefault
--app stringthe app slug (repo name) or appBlockId to pull (required)

Local dev against the real backend

The scaffold ships npm scripts for the inner dev loop (npm run dev:harness for the mock host, npm run dev:live for the real backend). Two app subcommands support the live loop and are invite-gated during the pre-GA beta:

  • civitai app dev-token <slug> mints a short-lived dev block token for npm run dev:live (real backend). Real generation that spends Buzz needs a full-scope personal API key.
  • civitai app dev-tunnel previews your local dev server rendered inside the real Civitai host (real session, real pickers, real Buzz) via a hardened reverse SSH tunnel.

See the Quickstart for the end-to-end flow.

Civitai Developer Documentation