The EmDash CLI provides commands for managing an EmDash CMS instance — database setup, type generation, content CRUD, schema management, media, and more.
Installation
The CLI is included with the emdash package:
npm install emdash
Run commands with npx emdash or add scripts to package.json. The binary is also available as em for brevity.
Authentication
Commands that talk to a running EmDash instance (everything except init, seed, export-seed, and auth secret) 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
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
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
emdash init
Initialize the database with core schema and optional template data.
npx emdash init [options]
Options
| Option | Alias | Description | Default |
|---|---|---|---|
--database | -d | Database file path | ./data.db |
--cwd | Working directory | Current directory | |
--force | -f | Re-run schema and seed | false |
Behavior
- Reads
emdashconfig frompackage.json - Creates the database file if needed
- Runs core migrations (creates system tables)
- Runs template
schema.sqlif configured - Runs template
seed.sqlif configured
emdash dev
Start the development server with automatic database setup.
npx emdash dev [options]
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
# Start dev server
npx emdash dev
# Custom port
npx emdash dev --port 3000
# Generate types from remote before starting
npx emdash dev --types
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
Generate TypeScript types from a running EmDash instance’s schema.
npx emdash types [options]
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
# Generate types from local dev server
npx emdash types
# Generate from remote instance
npx emdash types --url https://my-site.pages.dev
# Custom output path
npx emdash types --output src/types/emdash.ts
Behavior
- Fetches the schema from the instance
- Generates TypeScript type definitions
- Writes types to the output file
- Writes
schema.jsonalongside for reference
emdash login
Log in to an EmDash instance using OAuth Device Flow.
npx emdash login [options]
Options
| Option | Alias | Description | Default |
|---|---|---|---|
--url | -u | EmDash instance URL | http://localhost:4321 |
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
Log out and remove stored credentials.
npx emdash logout [options]
Options
| Option | Alias | Description | Default |
|---|---|---|---|
--url | -u | EmDash instance URL | http://localhost:4321 |
emdash whoami
Show the current authenticated user.
npx emdash whoami [options]
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
Manage content items. All subcommands use the remote API via EmDashClient.
content list <collection>
npx emdash content list posts
npx emdash content list posts --status published --limit 10
| Option | Description |
|---|---|
--status | Filter by status |
--limit | Maximum items |
--cursor | Pagination cursor |
content get <collection> <id>
npx emdash content get posts 01ABC123
npx 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 prove you’ve seen what you’re overwriting.
content create <collection>
npx emdash content create posts --data '{"title": "Hello"}'
npx emdash content create posts --file post.json --slug hello-world
cat 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 |
--status | Initial status (draft, published) |
Provide data via exactly one of --data, --file, or --stdin.
content update <collection> <id>
Like a file editor that requires you to read before you write — you must provide the _rev token from a prior get to prove you’ve seen the current state. This prevents accidentally overwriting changes you haven’t seen.
# 1. Read the item, note the _rev
npx emdash content get posts 01ABC123
# 2. Update with the _rev from step 1
npx 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>
npx emdash content delete posts 01ABC123
Soft-deletes the content item (moves to trash).
content publish <collection> <id>
npx emdash content publish posts 01ABC123
content unpublish <collection> <id>
npx emdash content unpublish posts 01ABC123
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>
npx emdash content restore posts 01ABC123
Restores a trashed content item.
emdash schema
Manage collections and fields.
schema list
npx emdash schema list
Lists all collections.
schema get <collection>
npx emdash schema get posts
Shows a collection with all its fields.
schema create <collection>
npx emdash schema create articles --label Articles
npx 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>
npx emdash schema delete articles
npx emdash schema delete articles --force
| Option | Description |
|---|---|
--force | Skip confirmation |
Prompts for confirmation unless --force is set.
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>
npx emdash schema remove-field posts featured
emdash media
Manage media items.
media list
npx emdash media list
npx 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>
npx emdash media upload ./photo.jpg
npx emdash media upload ./photo.jpg --alt "A sunset" --caption "Taken in Bristol"
| Option | Description |
|---|---|
--alt | Alt text |
--caption | Caption text |
media get <id>
npx emdash media get 01MEDIA123
media delete <id>
npx emdash media delete 01MEDIA123
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
Manage taxonomies and terms.
taxonomy list
npx emdash taxonomy list
taxonomy terms <name>
npx emdash taxonomy terms categories
npx emdash taxonomy terms tags --limit 50
| Option | Alias | Description |
|---|---|---|
--limit | -l | Maximum terms |
--cursor | Pagination cursor |
taxonomy add-term <taxonomy>
npx emdash taxonomy add-term categories --name "Tech" --slug tech
npx 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
Manage navigation menus.
menu list
npx emdash menu list
menu get <name>
npx emdash menu get primary
Returns the menu with all its items.
emdash seed
Apply a seed file to the database. This command works directly on a local SQLite file (no running server needed).
npx emdash seed [path] [options]
Arguments
| Argument | Description | Default |
|---|---|---|
path | Path to seed file | .emdash/seed.json |
Options
| Option | Alias | Description | Default |
|---|---|---|---|
--database | -d | Database file path | ./data.db |
--cwd | Working directory | Current directory | |
--validate | Validate only, don’t apply | false | |
--no-content | Skip sample content | false | |
--on-conflict | Conflict handling: skip, update, error | skip | |
--uploads-dir | Directory for media uploads | .emdash/uploads | |
--media-base-url | Base URL for media files | /_emdash/api/media/file | |
--base-url | Site base URL (for absolute media URLs) |
Seed File Resolution
The command looks for seed files in this order:
- Positional argument (if provided)
.emdash/seed.json(convention)- Path from
package.jsonemdash.seedfield
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.json
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
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 auth secret
Generate a secure authentication secret for your deployment.
npx emdash auth secret
Outputs a random secret suitable for EMDASH_AUTH_SECRET.
Generated Files
.emdash/types.ts
TypeScript interfaces generated by emdash types:
// 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
Raw schema export for tooling:
{
"version": "a1b2c3d4",
"collections": [
{
"slug": "posts",
"label": "Posts",
"fields": [...]
}
]
}
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_AUTH_SECRET | Secret for passkey authentication |
EMDASH_PREVIEW_SECRET | Secret for preview token generation |
Package Scripts
{
"scripts": {
"dev": "emdash dev",
"init": "emdash init",
"types": "emdash types",
"seed": "emdash seed",
"export-seed": "emdash export-seed",
"db:reset": "rm -f data.db && emdash init"
}
}
Exit Codes
| Code | Description |
|---|---|
0 | Success |
1 | Error (configuration, network, database) |