Command Line Interface
Complete guide for using the ObjectStack CLI to build metadata-driven applications
@objectstack/cli
Command Line Interface for building metadata-driven applications with the ObjectStack Protocol.
Installation
pnpm add -D @objectstack/cliThe CLI is available as objectstack or the shorter alias os.
Your First App in 2 Minutes
Create a project
npx @objectstack/cli init my-app
cd my-appThis scaffolds a working project with objectstack.config.ts, a sample object, and all dependencies installed.
Add more metadata
os generate object customer # Add a Customer object
os generate action approve # Add an action
os generate flow onboarding # Add an automation flowLaunch the Studio
os studioOpen http://localhost:3000/_studio/ — you'll see the Console UI with a data browser, metadata explorer, and API documentation.
Validate & Build
os validate # Check schema correctness
os compile # Build production artifact → dist/objectstack.jsonos studio = os serve --dev --ui. It starts a dev server with the Console UI, auto-loads ObjectQL, InMemory driver, and Hono HTTP server — zero config needed.
Commands
Development
| Command | Alias | Description |
|---|---|---|
os init [name] | Initialize a new ObjectStack project in the current directory | |
os dev [package] | Start development mode with hot reload | |
os serve [config] | Start the ObjectStack server with plugin auto-detection | |
os studio [config] | Launch dev server with Console UI at /_studio/ |
Production
| Command | Description |
|---|---|
os start | Serve a pre-compiled objectstack.json artifact (no objectstack.config.ts required) |
os init
Scaffolds a new ObjectStack project with configuration, TypeScript setup, and initial metadata files.
os init my-app # Create with default "app" template
os init my-plugin -t plugin # Create a plugin project
os init blank -t empty # Minimal config only
os init my-app --no-install # Skip dependency installationOptions:
-t, --template <template>— Template:app(default),plugin,empty--no-install— Skip automaticpnpm install
Templates:
| Template | What it creates |
|---|---|
app | Full application with objects, views, barrel imports |
plugin | Reusable plugin package with objects |
empty | Minimal project with just objectstack.config.ts |
os dev
Starts development mode. Three usage shapes:
- With local source (
objectstack.config.tsin cwd) — auto-compiles todist/objectstack.jsonif missing, then delegates toos serve --dev. - With a pre-built artifact (
--artifact <path|url>) — skips auto-compile and boots the artifact directly. Noobjectstack.config.tsneeded in cwd. Useful for trying out a published app in dev mode without cloning its source. - Monorepo root (cwd has
pnpm-workspace.yaml) — orchestratespnpm -r devacross packages.
os dev # Auto-compile cwd config, then start
os dev my-package # Workspace package (monorepo orchestration mode)
os dev --ui -v # Dev server with Studio UI + verbose
# Boot a remote artifact in dev mode (no local config needed)
os dev --artifact https://raw.githubusercontent.com/<org>/<repo>/main/dist/objectstack.json
# Override storage / auth on the fly
os dev --database file:./data/test.db --auth-secret $(openssl rand -hex 32)Options (the runtime overrides mirror os start — each flag overrides the matching env var):
| Flag | Env equivalent | Purpose |
|---|---|---|
-a, --artifact <path|url> | OS_ARTIFACT_PATH | Boot a pre-built artifact directly; skips auto-compile |
-d, --database <url> | OS_DATABASE_URL | file:… / libsql:// / postgres:// / mongodb:// / memory:// |
--database-driver <kind> | OS_DATABASE_DRIVER | Force sqlite | turso | postgres | mongodb | memory |
--database-auth-token <t> | OS_DATABASE_AUTH_TOKEN | libsql/Turso token |
--auth-secret <s> | AUTH_SECRET | Override the dev-fallback secret |
--project-id <id> | OS_PROJECT_ID | Project identifier (default proj_local) |
-p, --port <n> | PORT | Listen port |
--ui | — | Force Studio UI on (already on by default in dev) |
--no-compile | — | Skip the auto-compile step (errors if no artifact present) |
-v, --verbose | — | Verbose output |
os serve
Starts the ObjectStack server with automatic plugin discovery:
- Auto-loads ObjectQL Engine when objects are defined
- Auto-loads InMemory Driver in dev mode
- Auto-loads App Plugin for metadata
- Auto-loads Hono HTTP Server for REST APIs
- Auto-loads the
authtier plugins (@objectstack/plugin-auth,@objectstack/plugin-security,@objectstack/plugin-audit) when the preset includes theauthtier and the user did not pin them inobjectstack.config.ts
os serve # Default: port 3000
os serve -p 4000 # Custom port
os serve --dev # Development mode (pretty logs, devPlugins)
os serve --dev --ui # Dev mode with Console UI
os serve --no-server # Skip HTTP server (kernel only)
os serve --preset minimal # Skip auto-loaded auth/i18n/ui pluginsOptions:
-p, --port <port>— Server port (default: envPORTor3000)--dev— Development mode (loads devPlugins, pretty logging)--ui / --no-ui— Toggle Console UI at/_studio/(defaulton)--server / --no-server— Toggle HTTP server plugin--prebuilt— Skip esbuild /bundle-requireand load the config as native ESM (use this in production builds where the config is already pre-compiled)--preset minimal | default | full— Override the auto-registration tier (see below)
Tier presets
os serve decides which optional plugins to auto-register from a tier
list. Any plugin already present in config.plugins always wins; tiers
only gate the automatic registration of optional plugins.
| Preset | Tiers | Auto-loaded optional plugins |
|---|---|---|
minimal | core | none |
default (default) | core, i18n, ui, auth | i18n service, Studio UI, Auth + Security + Audit |
full | core, i18n, ui, ai, auth | adds the AI service tier |
The auth tier requires AUTH_SECRET to be set; otherwise AuthPlugin
is skipped with a yellow warning and the /api/v1/auth/* endpoints will
return 404. To take full control, set tiers on the stack config:
import { defineStack } from '@objectstack/spec';
export default defineStack({
manifest: { /* ... */ },
tiers: ['core'], // disable all optional auto-registration
plugins: [
// ... only what you explicitly want
],
});os studio
Launches the development server with the Console UI in one command. Equivalent to os serve --dev --ui.
The Console UI is a metadata-driven admin interface that provides:
- Object Explorer — Browse objects, view/edit data, inspect schemas
- Package Manager — View installed plugins and applications
- Developer Overview — Dashboard with runtime metadata summary
os studio # Default: port 3000
os studio -p 4000 # Custom portArchitecture:
┌─────────────────────────────────────────┐
│ os studio (:3000) │
├─────────────────────────────────────────┤
│ Hono Server │
│ ├─ /api/v1/* → ObjectStack API │
│ ├─ /_studio/* → Console SPA │
│ └─ /* → custom routes │
└─────────────────────────────────────────┘In development mode, /_studio/* requests are proxied to a Vite dev server
(spawned automatically on an internal port) with full HMR support. In
production, pre-built static files are served directly.
Production
os start
Boots a production server directly from a compiled objectstack.json artifact — no
objectstack.config.ts required. This is the canonical "deploy a built ObjectStack app"
command: hand a server one JSON file (or a URL pointing at one) and it runs.
# Quick start — load ./dist/objectstack.json with sqlite at .objectstack/data/standalone.db
os start
# Pick everything via flags (no env vars needed)
os start \
--artifact ./build/myapp.json \
--database file:./data/prod.db \
--auth-secret $(openssl rand -hex 32) \
--port 8080
# Remote artifact + Turso/libSQL backing store
os start \
--artifact https://cdn.example.com/app.json \
--database libsql://my-db.turso.io \
--database-auth-token $TURSO_TOKEN
# Postgres
os start --database "postgres://user:pass@host:5432/mydb"
# Pure env-var style still works (Docker / Fly / k8s friendly)
OS_ARTIFACT_PATH=./build/myapp.json \
OS_DATABASE_URL=file:./data/prod.db \
AUTH_SECRET=… \
os startOptions (all override the matching env var):
| Flag | Env equivalent | Purpose |
|---|---|---|
-a, --artifact <path|url> | OS_ARTIFACT_PATH | File path or http(s):// URL to the compiled artifact |
-d, --database <url> | OS_DATABASE_URL | file:… / libsql:// / postgres:// / mongodb:// / memory:// |
--database-driver <kind> | OS_DATABASE_DRIVER | Force sqlite | turso | postgres | mongodb | memory when the URL is ambiguous |
--database-auth-token <token> | OS_DATABASE_AUTH_TOKEN | Auth token for libsql/Turso |
--auth-secret <secret> | AUTH_SECRET | Secret for @objectstack/plugin-auth; without it /api/v1/auth/* is skipped (server still runs) |
--project-id <id> | OS_PROJECT_ID | Project identifier (default proj_local) |
-p, --port <port> | PORT | Listen port (default 3000) |
--ui | — | Opt-in. Mount Studio / Account / Console portals at /_studio/, /_account/, /_console/. Off by default in os start (Studio is a dev/admin surface). os dev mounts them by default. |
-v, --verbose | — | Verbose output |
Resolution priority (artifact): --artifact > OS_ARTIFACT_PATH > <cwd>/dist/objectstack.json.
Resolution priority (database): --database > OS_DATABASE_URL > TURSO_DATABASE_URL > file:.objectstack/data/standalone.db.
What it boots:
- Reads the artifact's
manifest,objects,views,flows, … - Auto-registers the platform services declared in
requires: [...](e.g.ai,automation,analytics,auth,ui) - Auto-detects the driver from the database URL scheme (
memory://→ in-memory,libsql:///https://→ Turso,postgres[ql]:///pg://→ pg,mongodb[+srv]://→ MongoDB, otherwise sqlite) - Runs
standaloneboot mode (no control plane). For single-/multi-project mode use a host config (apps/objectos-style).
Authentication:
The auth capability is auto-loaded only when both (1) the artifact declares requires: [..., 'auth'] and (2) a secret is provided via --auth-secret or AUTH_SECRET. Without a secret, AuthPlugin is silently skipped with a warning — the server still boots and serves data/REST routes, only /api/v1/auth/* (login/register) is omitted. This is intentional: os start is happy to run an unauthenticated, internal-network deployment.
os start vs os serve: os serve boots from objectstack.config.ts (TypeScript source).
os start boots from objectstack.json (compiled artifact) and falls back to the same
default-host path if you happen to run it without a config but with an artifact present.
The two commands ultimately go through the same kernel — they just differ in which input
shape they accept. See Source vs Artifact below.
Build & Validate
| Command | Description |
|---|---|
os compile [config] | Compile configuration to a JSON artifact (dist/objectstack.json) |
os validate [config] | Validate configuration against the ObjectStack Protocol schema |
os info [config] | Display metadata summary (objects, fields, apps, agents, etc.) |
os compile
Bundles and validates your objectstack.config.ts against the ObjectStackDefinitionSchema, then outputs a deployable JSON artifact.
os compile # Default output: dist/objectstack.json
os compile -o build/stack.json # Custom output path
os compile --json # JSON output for CI pipelinesOptions:
-o, --output <path>— Output path (default:dist/objectstack.json)--json— Output compile result as JSON (for CI)
Output example:
◆ Compile
────────────────────────────────────────
→ Loading configuration...
Config: objectstack.config.ts
Load time: 104ms
→ Validating protocol compliance...
→ Writing artifact...
✓ Build complete (312ms)
Data: 10 Objects 217 Fields
UI: 1 Apps 3 Dashboards 8 Reports 10 Actions
Logic: 5 Flows 5 Agents 2 APIs
Artifact: dist/objectstack.json (48.2 KB)The resulting dist/objectstack.json is a portable, self-describing deployment unit —
you can hand it to os start (locally or on a server), publish it to a CDN, or fetch it
over HTTP from another runtime. See os start and
Source vs Artifact for details.
os validate
Standalone schema validation with rich error output. Use to check your configuration without compiling.
os validate # Validate current directory
os validate --strict # Warnings as errors
os validate --json # JSON output for CI
os validate path/to/config # Validate specific fileOptions:
--strict— Treat warnings as errors (exit code 1)--json— Output results as JSON
Warnings checked:
- Missing
manifest.id(required for deployment) - Invalid
manifest.scope(must becloud,system, orproject) - No objects defined
- No apps or plugins defined
os info
Displays a summary of your metadata without compilation or validation:
os info # Show metadata summary
os info --json # JSON output for toolingOutput example:
◆ Info
────────────────────────────────────────
Enterprise CRM v3.0.0
com.example.crm
Namespace: crm
Type: app
Data: 10 Objects 217 Fields
UI: 1 Apps 3 Dashboards 8 Reports 10 Actions
Logic: 5 Flows 5 Agents 2 APIs
Objects:
account (16 fields, own) — Account
contact (24 fields, own) — Contact
...
Loaded in 90msScaffolding
| Command | Alias | Description |
|---|---|---|
os generate <type> <name> | os g | Generate metadata files |
os create <type> [name] | Create a new package from template |
os generate (alias: os g)
Generates properly typed metadata files with barrel index management.
os g object customer # Generate a Customer object
os g view customer # Generate a Customer list view
os g action approve # Generate an action
os g flow customer # Generate an automation flow
os g agent support # Generate an AI agent
os g dashboard sales # Generate a dashboard
os g app crm # Generate an app definition
os g object task -d lib/ # Override target directory
os g object task --dry-run # Preview without writingAvailable types:
| Type | Default Directory | Description |
|---|---|---|
object | src/objects/ | Business data object with fields |
view | src/views/ | List or form view definition |
action | src/actions/ | Button or batch action |
flow | src/flows/ | Automation flow |
agent | src/agents/ | AI agent |
dashboard | src/dashboards/ | Analytics dashboard |
app | src/apps/ | Application navigation |
Options:
-d, --dir <directory>— Override target directory--dry-run— Preview without writing files
What it does:
- Creates a typed TypeScript file using
Data.Object,UI.View,Automation.Flow, etc. - Creates or updates the barrel
index.tsin the target directory - Shows a hint to run
objectstack validate
os create
Creates new packages from built-in templates (for monorepo-level scaffolding):
os create plugin analytics # Create packages/plugins/plugin-analytics
os create example my-app # Create examples/my-appQuality
| Command | Description |
|---|---|
os test [files] | Run Quality Protocol test scenarios against a running server |
os doctor | Check development environment health |
os test
Runs Quality Protocol test scenarios (JSON-based BDD) against a running ObjectStack server.
os test # Default: qa/*.test.json
os test qa/my-test.json # Specific test file
os test --url http://localhost:4000 # Custom server URL
os test --token my-api-key # With authenticationos doctor
Checks your development environment and reports issues:
os doctor # Check health
os doctor -v # Show fix suggestions for warningsChecks performed:
- Node.js version (≥18 required)
- pnpm installation
- TypeScript availability
- Dependencies installed
@objectstack/specbuild status- Git availability
Authentication
| Command | Description |
|---|---|
os auth register | Create an account and store local credentials |
os auth login | Sign in and store credentials in ~/.objectstack/credentials.json |
os auth whoami | Show the current authenticated user |
os auth logout | Revoke the server session and clear local credentials |
os auth register
Creates a user account and stores the returned token locally.
os auth register
os auth register --email user@example.com --name "Jane Doe" --password secret
os auth register --url https://api.example.comos auth login
In an interactive terminal, login uses a browser-based device flow by default: the CLI prints a one-time verification URL, opens the browser, and polls until you approve access in Studio.
os auth login
os auth login --url https://api.example.com
os auth login --no-browserIf a valid token already exists, os auth login exits successfully with
"Already logged in as <email>". Use os auth logout to switch users, or pass
--force to re-authenticate.
For CI and other non-interactive contexts, pass email/password directly:
os auth login --email user@example.com --password secretos auth logout
Logout calls POST /api/v1/auth/sign-out before deleting local credentials, so
the server-side session is revoked as well.
os auth logoutCloud Projects
| Command | Description |
|---|---|
os projects list | List projects visible to the current session |
os projects show <id> | Show one project |
os projects create | Provision a new project |
os projects switch <id> | Set the active project for later CLI calls |
os projects bind <id> | Bind a compiled local artifact to an existing project |
Create a project from a local artifact
Compile first, then create a project and bind the generated
dist/objectstack.json in one call:
os compile
os projects create --org <org-id> --name CRM --artifact ./dist/objectstack.jsonThe server stores the absolute path in sys_project.metadata.artifact_path.
On project-kernel boot, ObjectOS loads the JSON bundle, registers schemas, and
seeds records from the bundle's data arrays.
Bind an existing project
os projects bind <project-id> --artifact ./dist/objectstack.json
os projects bind <project-id> --artifact ./dist/objectstack.json --build--build runs objectstack compile before updating the project. --reseed
is reserved for the server-side reseed endpoint; use it only when that endpoint
is available in your deployment.
Configuration
The CLI looks for objectstack.config.ts (or .js, .mjs) in the current directory:
import { defineStack } from '@objectstack/spec';
import * as objects from './src/objects';
import * as actions from './src/actions';
export default defineStack({
manifest: {
id: 'com.example.my-app',
namespace: 'my_app',
version: '1.0.0',
type: 'app',
name: 'My App',
description: 'My ObjectStack application',
},
objects: Object.values(objects),
actions: Object.values(actions),
});Config File Auto-Detection
The CLI searches for configuration files in this order:
objectstack.config.tsobjectstack.config.jsobjectstack.config.mjs
You can also specify a path explicitly:
os compile path/to/my-config.tsTypical Workflow
# 1. Create project
os init my-crm && cd my-crm
# 2. Define your data model
os g object account
os g object contact
os g object opportunity
# 3. Add business logic
os g flow lead-qualification
os g agent sales-assistant
# 4. Validate everything
os validate
# 5. Start development with Console UI
os studio
# 6. Build for production
os compile
# 7. Deploy: ship just the artifact
os start # locally
OS_ARTIFACT_PATH=https://cdn.you.com/app.json os start # remote artifactSource vs Artifact
ObjectStack treats objectstack.config.ts and objectstack.json as two forms of the same
schema — authoring source vs compiled artifact:
| Aspect | objectstack.config.ts | objectstack.json |
|---|---|---|
| Role | Authoring source | Deployable artifact |
| Format | TypeScript (defineStack({...})) | Pure JSON |
| May contain code | Yes (handler: async (ctx) => {...}) | No — handlers are lowered to a sibling objectstack-runtime.<hash>.mjs |
| Loaded by | os serve (via bundle-require) | os start (via loadArtifactBundle — file or http(s)://) |
| Schema | ObjectStackDefinitionSchema | Same schema, plus runtimeModule reference |
| Produced by | You (or os generate) | os compile / os build |
The artifact is fully self-describing: its requires: [...] field declares which platform
services (ai, automation, analytics, …) the runtime should auto-register, so os start
needs nothing other than the JSON itself to bring up a working server.
This is why an artifact is the canonical "portable deployment unit" — you can host it on S3 / GitHub raw / a CDN, and any ObjectStack runtime can fetch and execute it with no additional source code on the server.
Next Steps
- Examples Guide — Run the built-in example apps (Todo, CRM, BI)
- Developer Guide — Learn data modeling, security, and automation
- Protocol Reference — Complete schema documentation
CI/CD Integration
All commands that produce output support --json for machine-readable output:
# In CI pipeline
os validate --json --strict
os compile --json -o dist/objectstack.json
os info --jsonExample GitHub Actions step:
- name: Validate ObjectStack Config
run: npx objectstack validate --strict --json
- name: Build ObjectStack Artifact
run: npx objectstack compile --json