CLI Reference
forge new
Create a new project.
forge new [project-name] --demo|--minimal [options]
| Option | Description |
|---|---|
--demo | Full demo project with User CRUD, jobs, crons, workflows, webhooks |
--minimal | Clean scaffolding with empty directories and commented examples |
--output, -o <dir> | Output directory (defaults to project name) |
--no-lock | Skip generating bun.lock before initial commit |
One of --demo or --minimal is required.
# Demo project with working examples
forge new my-app --demo
# Clean slate for experienced developers
forge new my-app --minimal
# Custom output directory
forge new my-app --demo --output /path/to/projects/my-app
forge dev
Start the development environment using Docker Compose.
forge dev [action]
Actions
| Action | Description |
|---|---|
| (none) | Run docker compose up --build with backend, frontend, and PostgreSQL |
down | Stop the development environment |
down --clear | Stop, remove volumes, and delete target/ directory |
# Start development environment
forge dev
# Stop containers
forge dev down
# Stop and clean everything (volumes + target/)
forge dev down --clear
Requirements
| Tool | Minimum Version |
|---|---|
| Docker | 24+ (with Compose v2) |
Services
When running, the following services are available:
| Service | URL |
|---|---|
| Frontend | http://localhost:5173 |
| Backend | http://localhost:8080 |
PostgreSQL runs inside the Docker network and is not exposed to the host. The backend connects to it via the internal db hostname. To access the database directly, use docker compose exec:
docker compose exec db psql -U postgres -d my-app
docker compose exec db psql -U postgres -d my-app -c "SELECT * FROM users LIMIT 5"
Watch Scope
The backend container uses cargo-watch with an .ignore file (deny-all * with allowlist). Only these paths trigger backend restarts:
src/migrations/build.rsCargo.tomlCargo.lock.envforge.toml
forge check
Validate project configuration and dependencies.
forge check [options]
| Option | Description |
|---|---|
--config, -c <path> | Path to forge.toml (default: ./forge.toml) |
Checks Performed
- forge.toml validity and required sections
- Cargo.toml and forge dependency
- Directory structure (src/, src/schema/, src/functions/, migrations/)
- Migration file naming and
-- @upmarkers - Function files with forge macros (query, mutation, job, cron, workflow, daemon, webhook, mcp_tool)
- Schema files with
#[forge::model]or standard derives (Serialize,FromRow) - Generated file checksums (
.forge/directory) - Rust linting (cargo fmt, clippy)
- Frontend configuration (if present)
- Frontend linting (ESLint, Prettier)
# Full project check
forge check
# Custom config location
forge check --config ./config/forge.toml
forge generate
Generate frontend/runtime bindings from backend source code.
forge generate [options]
| Option | Description |
|---|---|
--force | Force regeneration even if files exist |
--output, -o <dir> | Output directory (default: frontend/src/lib/forge) |
--src, -s <dir> | Source directory to scan (default: src) |
--skip-runtime | Only regenerate types, skip runtime update |
--yes, -y | Auto-accept prompts (useful for CI) |
Generated Files
| File | Description |
|---|---|
| types.ts | TypeScript interfaces from Rust models |
| api.ts | Function bindings (queries, mutations) |
| stores.ts | Svelte store exports |
| runes.svelte.ts | Svelte 5 runes helpers |
| index.ts | Re-exports all modules |
| .forge/svelte/ | Runtime package (@forge/svelte) |
Backend handler/model files are authored in src/functions/ and src/schema/. forge generate then syncs generated frontend/runtime artifacts from that backend source of truth.
# Generate all TypeScript code
forge generate
# Force regenerate everything
forge generate --force
# Only update types (keep runtime)
forge generate --skip-runtime
# CI mode (no prompts)
forge generate -y
# Custom directories
forge generate --src ./backend/src --output ./web/src/lib/forge
forge migrate
Manage database migrations.
forge migrate [action] [options]
| Option | Description |
|---|---|
--config, -c <path> | Configuration file path (default: forge.toml) |
--migrations-dir, -m <dir> | Migrations directory (default: migrations) |
Actions
| Action | Description |
|---|---|
up | Run all pending migrations |
down [count] | Rollback the last N migrations (default: 1) |
status | Show migration status |
Automatic migrations
During development, migrations run automatically when the backend starts. Pending migrations are applied before the server accepts requests, so you don't need to run forge migrate up manually.
Manual migration management
Since PostgreSQL is only accessible inside the Docker network, use docker compose exec to run migration commands or interact with the database directly:
docker compose exec db psql -U postgres -d my-app -c "SELECT * FROM forge_migrations ORDER BY id"
docker compose exec backend forge migrate down
docker compose exec db psql -U postgres -d my-app
For production or CI, forge migrate connects via DATABASE_URL directly:
forge migrate up
forge migrate down
forge migrate up --config ./config/forge.toml --migrations-dir ./db/migrations
Migration File Format
Migration files must be named NNNN_name.sql (e.g., 0001_initial.sql) and contain -- @up marker.
-- @up
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email TEXT UNIQUE NOT NULL,
created_at TIMESTAMPTZ DEFAULT now()
);
-- @down
DROP TABLE users;
Environment Variables
| Variable | Description | Used By |
|---|---|---|
DATABASE_URL | PostgreSQL connection string (set automatically by docker-compose during dev) | forge migrate, runtime |
RUST_LOG | Log level (e.g., info, debug, trace) | forge dev |
HOST | Backend host (default: 0.0.0.0) | forge dev |
PORT | Backend port (default: 8080) | forge dev |
Exit Codes
| Code | Description |
|---|---|
| 0 | Success |
| 1 | Error (configuration, validation, or runtime failure) |