| title | CLI Reference |
|---|---|
| description | Command-line interface for EmDash CMS. |
import { Aside } from "@astrojs/starlight/components";
The EmDash CLI provides commands for managing an EmDash CMS instance — database setup, type generation, content CRUD, schema management, media, and more.
The CLI is included with the emdash package:
npm install emdashRun commands with npx emdash or add scripts to package.json. The binary is also available as em for brevity.
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.
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 |
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.
Initialize the database with core schema and optional template data.
npx emdash init [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 |
- 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
Start the development server with automatic database setup.
npx emdash dev [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 |
# Start dev server
npx emdash dev
# Custom port
npx emdash dev --port 3000
# Generate types from remote before starting
npx emdash dev --types- 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
Generate TypeScript types from a running EmDash instance's schema.
npx emdash types [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 |
# 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- Fetches the schema from the instance
- Generates TypeScript type definitions
- Writes types to the output file
- Writes
schema.jsonalongside for reference
Log in to an EmDash instance using OAuth Device Flow.
npx emdash login [options]| Option | Alias | Description | Default |
|---|---|---|---|
--url |
-u |
EmDash instance URL | http://localhost:4321 |
- 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.
Log out and remove stored credentials.
npx emdash logout [options]| Option | Alias | Description | Default |
|---|---|---|---|
--url |
-u |
EmDash instance URL | http://localhost:4321 |
Show the current authenticated user.
npx emdash whoami [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.
Manage content items. All subcommands use the remote API via EmDashClient.
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 |
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.
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.
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.
npx emdash content delete posts 01ABC123Soft-deletes the content item (moves to trash).
npx emdash content publish posts 01ABC123npx emdash content unpublish posts 01ABC123npx emdash content schedule posts 01ABC123 --at 2026-03-01T09:00:00Z| Option | Description |
|---|---|
--at |
ISO 8601 datetime (required) |
npx emdash content restore posts 01ABC123Restores a trashed content item.
Manage collections and fields.
npx emdash schema listLists all collections.
npx emdash schema get postsShows a collection with all its fields.
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 |
npx emdash schema delete articles
npx emdash schema delete articles --force| Option | Description |
|---|---|
--force |
Skip confirmation |
Prompts for confirmation unless --force is set.
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 |
npx emdash schema remove-field posts featuredManage media items.
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 |
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 |
npx emdash media get 01MEDIA123npx emdash media delete 01MEDIA123Full-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 |
Manage taxonomies and terms.
npx emdash taxonomy listnpx emdash taxonomy terms categories
npx emdash taxonomy terms tags --limit 50| Option | Alias | Description |
|---|---|---|
--limit |
-l |
Maximum terms |
--cursor |
Pagination cursor |
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) |
Manage navigation menus.
npx emdash menu listnpx emdash menu get primaryReturns the menu with all its items.
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]| Argument | Description | Default |
|---|---|---|
path |
Path to seed file | .emdash/seed.json |
| 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) |
The command looks for seed files in this order:
- Positional argument (if provided)
.emdash/seed.json(convention)- Path from
package.jsonemdash.seedfield
Export database schema and content as a seed file. Works directly on a local SQLite file.
npx emdash export-seed [options] > seed.json| 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 |
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
Generate a secure authentication secret for your deployment.
npx emdash auth secretOutputs a random secret suitable for EMDASH_AUTH_SECRET.
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;
}Raw schema export for tooling:
{
"version": "a1b2c3d4",
"collections": [
{
"slug": "posts",
"label": "Posts",
"fields": [...]
}
]
}| 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 |
{
"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"
}
}| Code | Description |
|---|---|
0 |
Success |
1 |
Error (configuration, network, database) |