Quick Start
This guide walks you through creating a simple CLI application with Padrone.
Installation
Section titled “Installation”Install Padrone and Zod:
# Using npmnpm install padrone zod
# Using bunbun add padrone zod
# Using pnpmpnpm add padrone zodCreate Your First CLI
Section titled “Create Your First CLI”Create a new file cli.ts:
import { createPadrone } from 'padrone';import * as z from 'zod/v4';
const program = createPadrone('greet') .configure({ version: '1.0.0', description: 'A friendly greeting CLI', }) .options( z.object({ name: z.string().describe('Name to greet'), excited: z.boolean().optional().describe('Add excitement'), }), { positional: ['name'] } ) .action((options) => { const greeting = `Hello, ${options.name}`; console.log(options.excited ? `${greeting}!` : greeting); });
program.cli();Run Your CLI
Section titled “Run Your CLI”# Run with a positional argumentbun cli.ts World# Output: Hello, World
# Run with the --excited flagbun cli.ts World --excited# Output: Hello, World!
# Show helpbun cli.ts --helpAdd Commands
Section titled “Add Commands”Most CLIs have multiple commands. Let’s add some:
import { createPadrone } from 'padrone';import * as z from 'zod/v4';
const program = createPadrone('todo') .configure({ version: '1.0.0', description: 'A simple todo CLI', }) .command('add', (c) => c .options( z.object({ task: z.string().describe('Task description'), priority: z.enum(['low', 'medium', 'high']).default('medium'), }), { positional: ['task'] } ) .action((options) => { console.log(`Added: ${options.task} [${options.priority}]`); }) ) .command('list', (c) => c .options( z.object({ all: z.boolean().optional().describe('Show completed tasks'), }) ) .action((options) => { console.log('Listing tasks...', { showAll: options.all }); }) );
program.cli();# Add a taskbun cli.ts add "Buy groceries" --priority high
# List tasksbun cli.ts list --allUse Option Aliases
Section titled “Use Option Aliases”Add short aliases for frequently used options:
z.object({ verbose: z.boolean().optional().describe('Verbose output').meta({ alias: 'v' }), output: z.string().optional().describe('Output file').meta({ alias: 'o' }),})Now users can use -v instead of --verbose and -o instead of --output.
Programmatic Usage
Section titled “Programmatic Usage”You can also run commands programmatically with full type safety:
// Run a command directlyprogram.run('add', { task: 'Buy milk', priority: 'high' });
// Generate a typed APIconst api = program.api();api.add({ task: 'Buy eggs', priority: 'low' });
// Parse without executingconst parsed = program.parse('add "Clean room" --priority medium');console.log(parsed.command); // 'add'console.log(parsed.options); // { task: 'Clean room', priority: 'medium' }Next Steps
Section titled “Next Steps”- Learn about Commands & Options in depth
- Integrate with AI tools
- Explore the API Reference