CLI Reference
The EmDash CLI provides commands for managing an EmDash CMS instance — database setup, type generation, content CRUD, schema management, media, and more.
Installation
Section titled “Installation”The CLI is included with the emdash package. Install it with the following command:
npm install emdashRun commands with npx emdash or add scripts to package.json. The binary is also available as em for brevity.
Authentication
Section titled “Authentication”Commands that talk to a running EmDash instance resolve authentication in this order:
--tokenflag — explicit token on the command lineEMDASH_TOKENenv var- Stored credentials from
~/.config/emdash/auth.json(saved byemdash login) - Dev bypass — if the URL is localhost and no token is available, automatically authenticates via the dev bypass endpoint
Most commands accept --url (default http://localhost:4321) and --token flags. When targeting a local dev server, no token is needed.
Common Flags
Section titled “Common Flags”These flags are available on all remote commands:
| Flag | Alias | Description | Default |
|---|---|---|---|
--url | -u | EmDash instance URL | http://localhost:4321 |
--token | -t | Auth token | From env/stored creds |
--json | Output as JSON (for piping) | Auto-detected from TTY |
Output
Section titled “Output”When stdout is a TTY, the CLI pretty-prints results with consola. When piped or when --json is set, it outputs raw JSON to stdout — suitable for jq or other tools.
Commands
Section titled “Commands”emdash dev
Section titled “emdash dev”Start the development server with automatic database setup.
npx emdash dev [options]Options
Section titled “Options”| Option | Alias | Description | Default |
|---|---|---|---|
--database | -d | Database file path | ./data.db |
--types | -t | Generate types from remote before starting | false |
--port | -p | Dev server port | 4321 |
--cwd | Working directory | Current directory |
Examples
Section titled “Examples”# Start dev servernpx emdash dev
# Custom portnpx emdash dev --port 3000
# Generate types from remote before startingnpx emdash dev --typesBehavior
Section titled “Behavior”- Checks for and runs pending database migrations
- If
--typesis set, generates TypeScript types from a remote instance (URL fromEMDASH_URLenv oremdash.urlinpackage.json) - Starts Astro dev server with
EMDASH_DATABASE_URLset
emdash types
Section titled “emdash types”Generate TypeScript types from a running EmDash instance’s schema.
npx emdash types [options]Options
Section titled “Options”| Option | Alias | Description | Default |
|---|---|---|---|
--url | -u | EmDash instance URL | http://localhost:4321 |
--token | -t | Auth token | From env/stored creds |
--output | -o | Output path for types | .emdash/types.ts |
--cwd | Working directory | Current directory |
Examples
Section titled “Examples”# Generate types from local dev servernpx emdash types
# Generate from remote instancenpx emdash types --url https://my-site.pages.dev
# Custom output pathnpx emdash types --output src/types/emdash.tsBehavior
Section titled “Behavior”- Fetches the schema from the instance
- Generates TypeScript type definitions
- Writes types to the output file
- Writes
schema.jsonalongside for reference
emdash login
Section titled “emdash login”Log in to an EmDash instance using OAuth Device Flow.
npx emdash login [options]Options
Section titled “Options”| Option | Alias | Description | Default |
|---|---|---|---|
--url | -u | EmDash instance URL | http://localhost:4321 |
Behavior
Section titled “Behavior”- Discovers auth endpoints from the instance
- If localhost and no auth configured, uses dev bypass automatically
- Otherwise initiates OAuth Device Flow — displays a code and opens your browser
- Polls for authorization, then saves credentials to
~/.config/emdash/auth.json
Saved credentials are used automatically by all subsequent commands targeting the same instance.
emdash logout
Section titled “emdash logout”Log out and remove stored credentials.
npx emdash logout [options]Options
Section titled “Options”| Option | Alias | Description | Default |
|---|---|---|---|
--url | -u | EmDash instance URL | http://localhost:4321 |
emdash whoami
Section titled “emdash whoami”Show the current authenticated user.
npx emdash whoami [options]Options
Section titled “Options”| Option | Alias | Description | Default |
|---|---|---|---|
--url | -u | EmDash instance URL | http://localhost:4321 |
--token | -t | Auth token | From env/stored creds |
--json | Output as JSON |
Displays email, name, role, auth method, and instance URL.
emdash content
Section titled “emdash content”Manage content items. All subcommands use the remote API via EmDashClient.
content list <collection>
Section titled “content list <collection>”npx emdash content list postsnpx emdash content list posts --status published --limit 10| Option | Description |
|---|---|
--status | Filter by status |
--limit | Maximum items |
--cursor | Pagination cursor |
content get <collection> <id>
Section titled “content get <collection> <id>”npx emdash content get posts 01ABC123npx emdash content get posts 01ABC123 --raw| Option | Description |
|---|---|
--raw | Return raw Portable Text (skip markdown conversion) |
The response includes a _rev token. Pass it to content update to confirm you have seen the current state before overwriting it.
content create <collection>
Section titled “content create <collection>”npx emdash content create posts --data '{"title": "Hello"}'npx emdash content create posts --file post.json --slug hello-worldcat post.json | npx emdash content create posts --stdin| Option | Description |
|---|---|
--data | JSON string with content data |
--file | Read data from a JSON file |
--stdin | Read data from stdin |
--slug | Content slug |
--locale | Content locale |
--translation-of | ID of a content item to link this as a translation of |
--draft | Keep as draft instead of auto-publishing |
Provide data via exactly one of --data, --file, or --stdin. New items are auto-published unless --draft is set.
content update <collection> <id>
Section titled “content update <collection> <id>”You must provide the _rev token from a prior get to prove you have seen the current state. This prevents overwriting changes you have not seen. The following steps read an item, then update it with that token:
# 1. Read the item, note the _revnpx emdash content get posts 01ABC123
# 2. Update with the _rev from step 1npx emdash content update posts 01ABC123 \ --rev MToyMDI2LTAyLTE0... \ --data '{"title": "Updated"}'| Option | Description |
|---|---|
--rev | Revision token from get (required) |
--data | JSON string with content data |
--file | Read data from a JSON file |
If the item has changed since your get, the server returns 409 Conflict — re-read and try again.
content delete <collection> <id>
Section titled “content delete <collection> <id>”npx emdash content delete posts 01ABC123Soft-deletes the content item (moves to trash).
content publish <collection> <id>
Section titled “content publish <collection> <id>”npx emdash content publish posts 01ABC123content unpublish <collection> <id>
Section titled “content unpublish <collection> <id>”npx emdash content unpublish posts 01ABC123content schedule <collection> <id>
Section titled “content schedule <collection> <id>”npx emdash content schedule posts 01ABC123 --at 2026-03-01T09:00:00Z| Option | Description |
|---|---|
--at | ISO 8601 datetime (required) |
content restore <collection> <id>
Section titled “content restore <collection> <id>”npx emdash content restore posts 01ABC123Restores a trashed content item.
emdash schema
Section titled “emdash schema”Manage collections and fields.
schema list
Section titled “schema list”npx emdash schema listLists all collections.
schema get <collection>
Section titled “schema get <collection>”npx emdash schema get postsShows a collection with all its fields.
schema create <collection>
Section titled “schema create <collection>”npx emdash schema create articles --label Articlesnpx emdash schema create articles --label Articles --label-singular Article --description "Blog articles"| Option | Description |
|---|---|
--label | Collection label (required) |
--label-singular | Singular label |
--description | Collection description |
schema delete <collection>
Section titled “schema delete <collection>”npx emdash schema delete articlesnpx emdash schema delete articles --force| Option | Description |
|---|---|
--force | Skip confirmation |
Prompts for confirmation unless --force is set.
schema add-field <collection> <field>
Section titled “schema add-field <collection> <field>”npx emdash schema add-field posts body --type portableText --label "Body Content"npx emdash schema add-field posts featured --type boolean --required| Option | Description |
|---|---|
--type | Field type: string, text, number, integer, boolean, datetime, image, reference, portableText, json (required) |
--label | Field label (defaults to field slug) |
--required | Whether the field is required |
schema remove-field <collection> <field>
Section titled “schema remove-field <collection> <field>”npx emdash schema remove-field posts featuredemdash media
Section titled “emdash media”Manage media items.
media list
Section titled “media list”npx emdash media listnpx emdash media list --mime image/png --limit 20| Option | Description |
|---|---|
--mime | Filter by MIME type |
--limit | Number of items |
--cursor | Pagination cursor |
media upload <file>
Section titled “media upload <file>”npx emdash media upload ./photo.jpgnpx emdash media upload ./photo.jpg --alt "A sunset" --caption "Taken in Bristol"| Option | Description |
|---|---|
--alt | Alt text |
--caption | Caption text |
media get <id>
Section titled “media get <id>”npx emdash media get 01MEDIA123media delete <id>
Section titled “media delete <id>”npx emdash media delete 01MEDIA123emdash search
Section titled “emdash search”Full-text search across content.
npx emdash search "hello world"npx emdash search "hello" --collection posts --limit 5| Option | Alias | Description |
|---|---|---|
--collection | -c | Filter by collection |
--limit | -l | Maximum results |
emdash taxonomy
Section titled “emdash taxonomy”Manage taxonomies and terms.
taxonomy list
Section titled “taxonomy list”npx emdash taxonomy listtaxonomy terms <name>
Section titled “taxonomy terms <name>”npx emdash taxonomy terms categoriesnpx emdash taxonomy terms tags --limit 50| Option | Alias | Description |
|---|---|---|
--limit | -l | Maximum terms |
--cursor | Pagination cursor |
taxonomy add-term <taxonomy>
Section titled “taxonomy add-term <taxonomy>”npx emdash taxonomy add-term categories --name "Tech" --slug technpx emdash taxonomy add-term categories --name "Frontend" --parent 01PARENT123| Option | Description |
|---|---|
--name | Term label (required) |
--slug | Term slug (defaults to slugified name) |
--parent | Parent term ID (for hierarchical taxonomies) |
emdash menu
Section titled “emdash menu”Manage navigation menus.
menu list
Section titled “menu list”npx emdash menu listmenu get <name>
Section titled “menu get <name>”npx emdash menu get primaryReturns the menu with all its items.
emdash export-seed
Section titled “emdash export-seed”Export database schema and content as a seed file. Works directly on a local SQLite file.
npx emdash export-seed [options] > seed.jsonOptions
Section titled “Options”| Option | Alias | Description | Default |
|---|---|---|---|
--database | -d | Database file path | ./data.db |
--cwd | Working directory | Current directory | |
--with-content | Include content (all or comma-separated collections) | ||
--no-pretty | Disable JSON formatting | false |
Output Format
Section titled “Output Format”The exported seed file includes:
- Settings: Site title, tagline, social links
- Collections: All collection definitions with fields
- Taxonomies: Taxonomy definitions and terms
- Menus: Navigation menus with items
- Widget Areas: Widget areas and widgets
- Content (if requested): Entries with
$mediareferences and$ref:syntax for portability
emdash secrets generate
Section titled “emdash secrets generate”Generate an EMDASH_ENCRYPTION_KEY for your deployment. The key is used to
encrypt plugin secrets at rest.
npx emdash secrets generatePrints the new key to stdout. Pipe it into your secret store, or write it
straight to a dev file with --write. The following commands write the key to .dev.vars or .env:
npx emdash secrets generate --write .dev.varsnpx emdash secrets generate --write .env--write refuses to overwrite an existing entry without --force.
Replacing a key in a deployment with existing encrypted data will leave
those secrets unreadable, so the protection is intentional.
emdash secrets fingerprint <key>
Section titled “emdash secrets fingerprint <key>”Print the 8-character fingerprint (kid) of a key without exposing its value. This is useful in CI for verifying the right key was deployed. The following command prints a key’s fingerprint:
npx emdash secrets fingerprint emdash_enc_v1_...Generated Files
Section titled “Generated Files”.emdash/types.ts
Section titled “.emdash/types.ts”The emdash types command generates TypeScript interfaces for each collection:
// Generated by EmDash CLI// Do not edit manually - run `emdash types` to regenerate
import type { PortableTextBlock } from "emdash";
export interface Post { id: string; title: string; content: PortableTextBlock[]; publishedAt: Date | null;}.emdash/schema.json
Section titled “.emdash/schema.json”The command also writes a raw schema export for tooling:
{ "version": "a1b2c3d4", "collections": [ { "slug": "posts", "label": "Posts", "fields": [...] } ]}Environment Variables
Section titled “Environment Variables”| Variable | Description |
|---|---|
EMDASH_DATABASE_URL | Database URL (set automatically by dev) |
EMDASH_TOKEN | Auth token for remote operations |
EMDASH_URL | Default remote URL for types and dev --types |
EMDASH_ENCRYPTION_KEY | Key for encrypting plugin secrets at rest. Operator-provided — never stored in the database. Generate with emdash secrets generate. |
EMDASH_PREVIEW_SECRET | Optional override for preview HMAC secret. When unset, EmDash generates and persists one in the options table. |
EMDASH_IP_SALT | Optional override for the commenter-IP hash salt. When unset, EmDash generates and persists one in the options table. |
EMDASH_AUTH_SECRET | Legacy. Used as the IP-salt source if set, so existing installs keep stable commenter-IP hashes across upgrade. New installs should not set this. |
Package scripts
Section titled “Package scripts”Add the CLI commands as package.json scripts for convenience:
{ "scripts": { "dev": "emdash dev", "types": "emdash types", "export-seed": "emdash export-seed", "db:reset": "rm -f data.db" }}Exit Codes
Section titled “Exit Codes”| Code | Description |
|---|---|
0 | Success |
1 | Error (configuration, network, database) |