CLI Reference
Complete reference for Radish CLI commands and workflows.
Installation
Global Installation
npm install -g radish-cli
Local Development
# From the CLI repo root
npm install
npm link # or: npm install -g .
Check Version
radish-cli --version
Commands
create datalayer
Generate a datalayer from a blueprint.
radish-cli create datalayer <output-path> [options]
Arguments:
<output-path>- Directory to generate code in (e.g.,.,./my-app)
Options:
| Option | Description | Default |
|---|---|---|
--app-name <name> | Friendly app name (for DB & UI) | Directory name |
--preset <name> | Built-in sample (todo, library) | library |
--schema <path> | Path to custom types blueprint | - |
--db-url <url> | Database URL for seeding | mongodb://localhost:27017 |
--seed | Auto-seed database after generation | false |
--dry | Dry run - show files without writing | false |
Examples:
# Basic generation with library preset
radish-cli create datalayer ./my-app
# With custom schema
radish-cli create datalayer . --schema ./blueprints/app.types.yml
# With database seeding
radish-cli create datalayer . --seed --db-url mongodb://localhost:27017/mydb
# Dry run to preview files
radish-cli create datalayer . --dry
console
Launch the interactive datalayer inspector.
radish-cli console <app-path> [options]
Arguments:
<app-path>- Path to Radish-generated app (default:.)
Options:
| Option | Description | Default |
|---|---|---|
-p, --port <port> | Port to run console on | 5173 |
--build | Build for production instead of dev | false |
Examples:
# Launch console for current directory
radish-cli console .
# Launch on custom port
radish-cli console ./my-app --port 3000
# Build for production
radish-cli console . --build
verify
Verify that generated code matches the current blueprint.
radish-cli verify [app-path] [options]
Arguments:
[app-path]- Path to app directory (default:.)
Options:
| Option | Description | Default |
|---|---|---|
--verbose | Show detailed hash comparison | false |
Exit codes:
0- Generated code matches blueprint1- Generated code out of sync with blueprint
Examples:
# Basic verification
radish-cli verify .
# Verbose output with hash details
radish-cli verify . --verbose
# Use in CI/CD
radish-cli verify || exit 1
info
Display manifest information about generated code.
radish-cli info [app-path] [options]
Arguments:
[app-path]- Path to app directory (default:.)
Options:
| Option | Description | Default |
|---|---|---|
--json | Output as JSON | false |
Examples:
# Human-readable info
radish-cli info .
# JSON output for scripting
radish-cli info . --json
# Extract specific fields
radish-cli info . --json | jq '.radishVersion'
clean
Remove all Radish-generated code and configuration.
radish-cli clean [app-path] [options]
Arguments:
[app-path]- Path to app directory (default:.)
Options:
| Option | Description | Default |
|---|---|---|
--dry-run | Show what would be removed without removing | false |
--force | Skip confirmation prompts | false |
Examples:
# Clean with confirmation
radish-cli clean .
# Dry run to see what would be removed
radish-cli clean . --dry-run
# Force clean without prompts
radish-cli clean . --force
Workflows
Initial Setup
Create your first Radish project:
# 1. Create project directory
mkdir my-app && cd my-app
# 2. Create blueprint
mkdir blueprints
cat > blueprints/app.types.yml << 'EOF'
version: 1
defaults:
owned: true
timestamps: true
entities:
Task:
plural: tasks
fields:
title: { type: string, required: true }
done: { type: boolean, default: false }
filters: [done]
EOF
# 3. Generate datalayer
radish-cli create datalayer . --schema blueprints/app.types.yml
# 4. Launch console to explore
radish-cli console .
Regeneration
Regenerate after blueprint changes:
# 1. Edit blueprint
vim blueprints/app.types.yml
# 2. Regenerate (same command as initial generation)
radish-cli create datalayer . --schema blueprints/app.types.yml
# 3. Review changes
git diff .radish/
# 4. Verify manifest changes
cat .radish/MANIFEST.json | jq '.blueprints.types.hash'
# 5. Test your app
npm test
# 6. Commit blueprint + generated code together
git add blueprints/ .radish/
git commit -m "feat: add description field to Task"
Blueprint Verification
Check if generated code matches your current blueprint:
# View blueprint hash from manifest
cat .radish/MANIFEST.json | jq '.blueprints.types.hash'
# Output: "sha256:89f21a4b2c3d4e5f"
# Manually compute hash of current blueprint
cat blueprints/app.types.yml | sha256sum | head -c 16
# Compare the hashes - they should match
If hashes don't match: Generated code is out of sync with blueprint. Regenerate:
radish-cli create datalayer . --schema blueprints/app.types.yml
Automated verification commands:
# Verify generated code matches blueprint
radish-cli verify # Exit 0 if match, exit 1 if mismatch
radish-cli verify --verbose # Show detailed hash comparison
# Display manifest information
radish-cli info # Human-readable format
radish-cli info --json # Machine-readable JSON output
Future CLI commands (planned):
radish-cli compare staging # Compare local vs deployed manifests
Version Management
Check Generated Version
View generation metadata and blueprint hash:
# View top-level manifest
cat .radish/MANIFEST.json
# View datalayer-specific manifest
cat .radish/lib/datalayer/MANIFEST.json
Top-level manifest (.radish/MANIFEST.json):
{
"$schema": "https://radish-cli.dev/schemas/manifest.v1.json",
"manifestVersion": "1.0",
"radishVersion": "0.6.0",
"projectName": "my-app",
"generatedAt": "2026-03-11T10:30:00.000Z",
"blueprints": {
"types": {
"path": "blueprints/app.types.yml",
"hash": "sha256:89f21a4b2c3d4e5f",
"lastModified": "2026-03-11T09:15:00.000Z"
}
},
"layers": {
"datalayer": {
"enabled": true,
"manifestPath": "lib/datalayer/MANIFEST.json",
"version": "1.0.0"
}
}
}
Datalayer manifest (.radish/lib/datalayer/MANIFEST.json):
{
"$schema": "https://radish-cli.dev/schemas/datalayer-manifest.v1.json",
"manifestVersion": "1.0",
"layer": "datalayer",
"radishVersion": "0.6.0",
"blueprint": {
"path": "blueprints/app.types.yml",
"hash": "sha256:89f21a4b2c3d4e5f",
"entities": 12,
"builtinEntities": 3,
"customEntities": 9
},
"entities": [
{
"name": "Task",
"type": "custom",
"builtin": false,
"fields": 5,
"relationships": ["User"],
"features": {
"versioning": false,
"filtering": true,
"population": true
}
}
],
"generated": {
"contracts": { "files": 18 },
"models": { "files": 12 },
"services": { "files": 14 }
}
}
Use cases:
- Check CLI version used for generation
- Verify blueprint hash matches current blueprint
- See entity counts and generated file counts
- Debug regeneration issues
- Compare manifests across environments
Update CLI Version
# 1. Update CLI
npm update -g radish-cli
# 2. Check new version
radish-cli --version
# 3. Read changelog
cat node_modules/radish-cli/CHANGELOG.md
# 4. Regenerate
radish-cli create datalayer . --schema blueprints/app.types.yml
# 5. Review changes
git diff .radish/
# 6. Commit
git commit -m "chore: regenerate with radish-cli v0.6.0"
Semantic Versioning
Radish CLI follows semantic versioning (MAJOR.MINOR.PATCH):
| Version Change | Risk | Description | Action Required |
|---|---|---|---|
| MAJOR (0.x → 1.x) | 🔴 High | Breaking changes in generated API | Review CHANGELOG, update code, test thoroughly |
| MINOR (0.6.x → 0.7.x) | 🟡 Low-Medium | New features, non-breaking | Safe to regenerate, optional feature adoption |
| PATCH (0.6.0 → 0.6.1) | 🟢 Low | Bug fixes only | Safe to regenerate immediately |
Schema Migrations
Safe Changes (No Migration Required)
These changes are backward-compatible:
- ✅ Adding optional fields
- ✅ Adding new entities
- ✅ Changing field labels/descriptions
- ✅ Adding indexes
# Before
Task:
fields:
title: { type: string, required: true }
# After - SAFE
Task:
fields:
title: { type: string, required: true }
description: { type: string, optional: true } # ✅ Optional
Action: Regenerate and deploy immediately.
Breaking Changes (Migration Required)
These changes require database migration:
- ⚠️ Adding required fields
- ⚠️ Changing field types
- ⚠️ Removing fields
- ⚠️ Renaming fields
# Before
Task:
fields:
title: { type: string, required: true }
# After - BREAKING
Task:
fields:
title: { type: string, required: true }
priority: { type: int, required: true } # 🔴 Required!
Migration Workflow:
# 1. Backup database
mongodump --db myapp --out ./backup-$(date +%Y%m%d)
# 2. Write migration script
cat > scripts/migrate-add-priority.js << 'EOF'
const { MongoClient } = require('mongodb');
async function migrate() {
const client = new MongoClient(process.env.MONGO_URL);
await client.connect();
const db = client.db();
const tasks = db.collection('tasks');
// Add required field with default value
await tasks.updateMany(
{ priority: { $exists: false } },
{ $set: { priority: 1 } }
);
console.log('Migration complete');
await client.close();
}
migrate();
EOF
# 3. Test migration on backup
mongorestore backup/
MONGO_URL=mongodb://localhost:27017/myapp_test node scripts/migrate-add-priority.js
# 4. Update blueprint
vim blueprints/app.types.yml
# 5. Regenerate
radish-cli create datalayer . --schema blueprints/app.types.yml
# 6. Test thoroughly
npm test
# 7. Deploy migration + code together
Migration Decision Matrix
| Change | DB Migration? | Code Changes? | Example |
|---|---|---|---|
| Add optional field | ❌ No | ❌ No | bio: { optional: true } |
| Add required field | ✅ Yes | 🟡 Maybe | priority: { required: true } |
| Remove field | 🟡 Optional | ❌ No | Delete from YAML |
| Rename field | ✅ Yes | ✅ Yes | Copy data to new field |
| Change type | ✅ Yes | ✅ Yes | string → int |
| Add entity | ❌ No | ❌ No | New entity in YAML |
| Add index | ❌ No | ❌ No | Auto-created |
Troubleshooting
"Cannot find module" after regeneration
Cause: Package structure changed or dependencies not installed.
Solution:
# Reinstall dependencies in generated packages
cd .radish/lib/datalayer/contracts && npm install
cd ../server && npm install
Tests failing after regeneration
Cause: Breaking change in generated API.
Solution:
- Review CHANGELOG for breaking changes
- Update test code to use new APIs
- Check for schema naming convention changes
Database validation errors
Cause: Schema changed but database has old data.
Solution:
- Run migration script before deploying
- Ensure all required fields have values
- Check field type compatibility
"File already exists" error
Cause: Generating to wrong directory or permissions issue.
Solution:
- Verify output path is correct
- Check directory permissions
- Use
--dryflag to preview first
Best Practices
1. Commit Blueprint + Generated Code Together
git add blueprints/ .radish/
git commit -m "feat: add Task entity"
Makes code review easier and keeps blueprint changes visible alongside generated changes.
2. Test After Every Regeneration
npm test # Run full test suite
Even "safe" changes can have unexpected effects.
3. Use Version Control
# Never regenerate without committing first
git status
git commit -m "checkpoint before regeneration"
radish-cli create datalayer .
Easy rollback if regeneration causes issues.
4. Pin CLI Version in CI
# .github/workflows/ci.yml
- name: Install Radish CLI
run: npm install -g radish-cli@0.6.0 # Pin specific version
Ensures consistent builds across environments.
5. Monitor for Updates
- Watch Radish CLI releases on GitHub
- Subscribe to changelog notifications
- Update regularly for bug fixes
Environment Variables
| Variable | Description | Default |
|---|---|---|
RADISH_APP_PATH | Path to app (console command) | Current directory |
PORT | Console port | 5173 |
MONGO_URL | Database connection string | mongodb://localhost:27017 |
Generated Files
After running create datalayer, you'll have:
.radish/
├── MANIFEST.json # Top-level generation metadata
├── README.md # Generated code guide
├── docs/ # Radish CLI documentation (copied)
│ ├── INDEX.md
│ ├── getting-started.md
│ └── ...
└── lib/
└── datalayer/
├── MANIFEST.json # Datalayer-specific metadata
├── package.json # @generated/datalayer package
├── contracts/ # Zod schemas & TypeScript types
│ ├── common.ts
│ ├── task.ts
│ ├── index.ts
│ └── metadata/ # Field metadata for runtime introspection
├── server/
│ ├── models/ # MongoDB models
│ ├── repos/ # Data access layer
│ ├── services/ # Business logic with permissions
│ ├── routes/ # HTTP API routes (SvelteKit)
│ │ └── api/v1/ # Versioned API endpoints
│ ├── auth/ # Authentication adapters
│ └── seeds/ # Database seeders
├── docs/ # App-specific generated documentation
│ ├── API.md # Complete API reference
│ ├── services.md # Service layer docs
│ ├── types.md # TypeScript types
│ ├── roles.md # Auth & permissions
│ ├── AI_CONTEXT.md # AI-friendly summary
│ └── openapi.json # OpenAPI 3.0 spec
Key files:
- MANIFEST.json files - Track blueprint hashes and generation metadata
- package.json - Self-contained dependencies for generated code
- contracts/ - Type-safe schemas and types for your entities
- server/ - Complete backend implementation (models, repos, services, routes)
- docs/ - Auto-generated API documentation
Next Steps
- Blueprint Reference - Learn blueprint syntax
- [Generated Code]../datalayer/overview.md) - Understand what gets generated
- Getting Started - Step-by-step tutorial