Skip to main content

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:

OptionDescriptionDefault
--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 seedingmongodb://localhost:27017
--seedAuto-seed database after generationfalse
--dryDry run - show files without writingfalse

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:

OptionDescriptionDefault
-p, --port <port>Port to run console on5173
--buildBuild for production instead of devfalse

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:

OptionDescriptionDefault
--verboseShow detailed hash comparisonfalse

Exit codes:

  • 0 - Generated code matches blueprint
  • 1 - 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:

OptionDescriptionDefault
--jsonOutput as JSONfalse

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:

OptionDescriptionDefault
--dry-runShow what would be removed without removingfalse
--forceSkip confirmation promptsfalse

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 ChangeRiskDescriptionAction Required
MAJOR (0.x → 1.x)🔴 HighBreaking changes in generated APIReview CHANGELOG, update code, test thoroughly
MINOR (0.6.x → 0.7.x)🟡 Low-MediumNew features, non-breakingSafe to regenerate, optional feature adoption
PATCH (0.6.0 → 0.6.1)🟢 LowBug fixes onlySafe 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

ChangeDB Migration?Code Changes?Example
Add optional field❌ No❌ Nobio: { optional: true }
Add required field✅ Yes🟡 Maybepriority: { required: true }
Remove field🟡 Optional❌ NoDelete from YAML
Rename field✅ Yes✅ YesCopy data to new field
Change type✅ Yes✅ Yesstringint
Add entity❌ No❌ NoNew entity in YAML
Add index❌ No❌ NoAuto-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:

  1. Review CHANGELOG for breaking changes
  2. Update test code to use new APIs
  3. Check for schema naming convention changes

Database validation errors

Cause: Schema changed but database has old data.

Solution:

  1. Run migration script before deploying
  2. Ensure all required fields have values
  3. Check field type compatibility

"File already exists" error

Cause: Generating to wrong directory or permissions issue.

Solution:

  1. Verify output path is correct
  2. Check directory permissions
  3. Use --dry flag 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

VariableDescriptionDefault
RADISH_APP_PATHPath to app (console command)Current directory
PORTConsole port5173
MONGO_URLDatabase connection stringmongodb://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