Bunli uses a configuration file to define CLI metadata, build settings, plugins, and more. The config is validated at runtime using Zod schemas for type safety.
Configuration File
Create a bunli.config.ts file in your project root:
import { defineConfig } from '@bunli/core'
export default defineConfig({
name: 'my-cli',
version: '1.0.0',
description: 'A powerful CLI tool',
commands: {
entry: './cli.ts',
directory: './commands'
},
build: {
entry: 'cli.ts',
outdir: 'dist',
targets: ['native'],
minify: true
},
plugins: []
})
Bunli also supports bunli.config.js and bunli.config.mjs for JavaScript projects.
defineConfig
The defineConfig function provides type safety and IntelliSense:
import { defineConfig } from '@bunli/core'
import type { BunliConfigInput } from '@bunli/core'
const config: BunliConfigInput = {
// TypeScript will validate this
}
export default defineConfig(config)
Configuration Options
CLI name shown in help output and package.json.
CLI version (usually from package.json).
Brief description of your CLI.description: 'A modern CLI tool for developers'
Commands Configuration
Commands discovery and generation settings.Entry point file for your CLI. Directory containing command files. Generate a commands report during type generation.
Build Configuration
Build and compilation settings.Entry point(s) for building.entry: 'cli.ts'
// or multiple entries
entry: ['cli.ts', 'server.ts']
Output directory for built files. Build targets (e.g., 'native', 'bun-linux-x64', 'bun-darwin-arm64').targets: ['native'] // Current platform
targets: ['bun-linux-x64', 'bun-darwin-arm64'] // Cross-platform
Compress output binaries. Minify JavaScript output. External dependencies to exclude from bundle.external: ['@bunli/core', 'zod']
Development Configuration
Development mode settings.Port for dev server (if applicable).
Test Configuration
Test execution settings.test.pattern
string | string[]
default:"['**/*.test.ts', '**/*.spec.ts']"
Test file patterns.pattern: ['**/*.test.ts', '**/*.spec.ts']
Enable coverage reporting.
Workspace Configuration
Monorepo and workspace settings.Workspace package patterns.packages: ['packages/*', 'apps/*']
workspace.versionStrategy
'fixed' | 'independent'
default:"'fixed'"
Versioning strategy for workspace packages.versionStrategy: 'independent'
Shared workspace configuration.
Release Configuration
Publishing and release settings.release.tagFormat
string
default:"'v{{version}}'"
Git tag format.tagFormat: 'v{{version}}'
release.conventionalCommits
Use conventional commits for changelog.conventionalCommits: true
Binary publishing configuration (per-platform packages).release.binary.packageNameFormat
string
default:"'{{name}}-{{platform}}'"
Format for platform-specific package names.packageNameFormat: '{{name}}-{{platform}}'
release.binary.shimPath
string
default:"'bin/run.mjs'"
Plugin Configuration
plugins
PluginConfig[]
default:"[]"
Array of plugins to load.import { defineConfig } from '@bunli/core'
import metricsPlugin from './plugins/metrics'
export default defineConfig({
plugins: [
metricsPlugin({ enabled: true })
]
})
See Plugins for details.
TUI Configuration
Terminal UI rendering settings.Renderer configuration.Terminal buffer mode.
alternate: Full-screen alternate buffer (like vim)
standard: Render in main buffer (scrollback-friendly)
tui: {
renderer: {
bufferMode: 'alternate'
}
}
Help Configuration
Custom help rendering.Custom help renderer function.import type { HelpRenderer } from '@bunli/core'
const customHelp: HelpRenderer = (context) => {
console.log(`${context.cliName} v${context.version}`)
// Custom help formatting
}
export default defineConfig({
help: {
renderer: customHelp
}
})
Loading Configuration
Bunli automatically loads configuration from your project root:
import { loadConfig, loadConfigResult } from '@bunli/core'
// Load config (throws on error)
const config = await loadConfig()
// Load config with Result type (better-result pattern)
const result = await loadConfigResult()
if (result.isOk()) {
const config = result.value
} else {
const error = result.error
// Handle ConfigNotFoundError or ConfigLoadError
}
Config Loading Order
Bunli searches for config files in this order:
bunli.config.ts
bunli.config.js
bunli.config.mjs
Real-World Examples
Simple CLI
Development Server
Production CLI
import { defineConfig } from '@bunli/core'
export default defineConfig({
name: 'my-cli',
version: '1.0.0',
description: 'A simple CLI tool',
commands: {
entry: './cli.ts'
},
build: {
entry: 'cli.ts',
outdir: 'dist',
targets: ['native']
}
})
import { defineConfig } from '@bunli/core'
export default defineConfig({
name: 'dev-server',
version: '0.0.1',
description: 'Development server with plugins',
commands: {
entry: './cli.ts',
directory: './commands'
},
build: {
entry: 'cli.ts',
outdir: 'dist',
targets: ['native'],
minify: true,
sourcemap: false
},
dev: {
watch: true,
inspect: false
},
test: {
pattern: ['**/*.test.ts'],
coverage: true
}
})
import { defineConfig } from '@bunli/core'
import completionsPlugin from '@bunli/plugin-completions'
export default defineConfig({
name: 'prod-cli',
version: '2.1.0',
description: 'Production-ready CLI',
commands: {
entry: './src/cli.ts',
directory: './src/commands',
generateReport: true
},
build: {
entry: 'src/cli.ts',
outdir: 'dist',
targets: [
'bun-linux-x64',
'bun-darwin-arm64',
'bun-windows-x64'
],
compress: true,
minify: true,
external: ['@bunli/core']
},
release: {
npm: true,
github: true,
conventionalCommits: true,
binary: {
packageNameFormat: '{{name}}-{{platform}}',
shimPath: 'bin/run.mjs'
}
},
plugins: [
completionsPlugin()
]
})
Type-Safe Configuration
Bunli validates your configuration at runtime:
import { bunliConfigSchema } from '@bunli/core'
import { z } from 'zod'
// Get the TypeScript type
type BunliConfig = z.infer<typeof bunliConfigSchema>
// Validate a config object
const result = bunliConfigSchema.safeParse(myConfig)
if (!result.success) {
console.error(result.error)
}
Overriding Configuration
You can override config when creating a CLI:
import { createCLI } from '@bunli/core'
const cli = await createCLI({
name: 'my-cli',
version: '1.0.0',
// Overrides bunli.config.ts
})
Best Practices
Use TypeScript for config
TypeScript provides IntelliSense and type checking.// bunli.config.ts (recommended)
export default defineConfig({ /* ... */ })
Keep config minimal
Only configure what you need. Bunli provides sensible defaults.
Use environment variables
Don’t hardcode secrets in config files.export default defineConfig({
plugins: [
apiPlugin({ apiKey: process.env.API_KEY })
]
})
Validate plugin options
Use Zod schemas to validate plugin configuration.
See Also