Bunli
Core Concepts

Configuration

Configure your Bunli CLI project with bunli.config.ts

Configuration

Configure your Bunli CLI project behavior with bunli.config.ts.

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: 'My awesome CLI tool',
  
  // Command options (REQUIRED)
  commands: {
    directory: './commands'  // Must use commands/ directory
  },
  
  // Build configuration
  build: {
    entry: './cli.ts',
    outdir: './dist',
    targets: ['native'],  // Default target
    compress: false,      // Default: false
    minify: false,        // Default: false
    sourcemap: true       // Default: true
  },
  
  // Plugins (REQUIRED - can be empty array)
  plugins: []
})

Configuration Options

Basic Information

export default defineConfig({
  // CLI name (defaults to package.json name)
  name: 'my-cli',
  
  // Version (defaults to package.json version)
  version: '1.0.0',
  
  // Description for help text
  description: 'A powerful CLI tool'
})

Command Configuration

export default defineConfig({
  commands: {
    // Where to find command files (REQUIRED)
    directory: './commands',  // Must use commands/ directory
    
    // Command manifest for lazy loading (optional)
    manifest: './commands/manifest.ts'
  }
})

All Bunli projects must use a commands/ directory structure for reliable type generation. The commands.directory configuration is required.

Build Configuration

export default defineConfig({
  build: {
    // Entry point (default: './cli.ts')
    entry: './cli.ts',
    
    // Output directory (default: './dist')
    outdir: './dist',
    
    // Target platforms (default: ['native'])
    targets: ['native'],  // Native for current platform
    // or specific platforms:
    // targets: ['darwin-arm64', 'linux-x64', 'windows-x64'],
    
    // Compress output archives (default: false)
    compress: false,
    
    // External dependencies (not bundled)
    external: ['sqlite3', 'sharp'],
    
    // Minify output (default: false)
    minify: false,
    
    // Generate sourcemaps (default: true)
    sourcemap: true
  }
})

Development Configuration

export default defineConfig({
  dev: {
    // Watch for file changes
    watch: true,
    
    // Enable Node.js inspector
    inspect: true,
    
    // Inspector port
    port: 9229
  }
})

Type Generation

Type generation is automatically enabled in all Bunli projects for enhanced developer experience:

export default defineConfig({
  name: 'my-cli',
  version: '1.0.0',
})

Default Behavior:

SettingDefaultDescription
Auto-GenerationtrueAlways enabled
Commands Directory./commandsWhere to find command files (REQUIRED)
Output File./.bunli/commands.gen.tsGenerated types location
Watch Modetrue in devRegenerate on file changes
Plugins[]Empty array (REQUIRED)

Type generation is automatically integrated with bunli dev and bunli build commands. Learn more in the Type Generation Guide.

Test Configuration

export default defineConfig({
  test: {
    // Test file patterns
    pattern: ['**/*.test.ts', '**/*.spec.ts'],
    
    // Coverage reporting
    coverage: true,
    
    // Watch mode
    watch: false
  }
})

Release Configuration

export default defineConfig({
  release: {
    // Publish to npm
    npm: true,
    
    // Create GitHub release
    github: true,
    
    // Git tag format
    tagFormat: 'v${version}',
    
    // Use conventional commits
    conventionalCommits: true
  }
})

Workspace Configuration

For monorepos:

export default defineConfig({
  workspace: {
    // Package locations
    packages: ['packages/*', 'apps/*'],
    
    // Shared configuration
    shared: {
      typescript: true,
      eslint: true
    },
    
    // Version strategy
    versionStrategy: 'independent' // or 'fixed'
  }
})

Environment-Specific Config

Use environment variables or conditions:

export default defineConfig({
  name: 'my-cli',
  build: {
    minify: process.env.NODE_ENV === 'production',
    sourcemap: process.env.DEBUG === 'true',
    targets: process.env.CI 
      ? ['darwin-arm64', 'linux-x64', 'windows-x64']
      : [process.platform + '-' + process.arch]
  }
})

Extending Configuration

Share configuration across projects:

// base.config.ts
export const baseConfig = {
  build: {
    minify: true,
    compress: true
  }
}

// bunli.config.ts
import { defineConfig } from '@bunli/core'
import { baseConfig } from './base.config'

export default defineConfig({
  ...baseConfig,
  name: 'my-cli',
  build: {
    ...baseConfig.build,
    entry: './src/index.ts'
  }
})

Platform-Specific Builds

Configure different settings per platform:

const platforms = {
  'darwin-arm64': {
    external: ['fsevents']
  },
  'windows-x64': {
    external: ['node-gyp']
  }
}

export default defineConfig({
  build: {
    targets: Object.keys(platforms),
    // Platform-specific externals handled by build process
  }
})

Configuration Schema

The configuration is validated using Zod:

const configSchema = z.object({
  name: z.string().optional(),
  version: z.string().optional(),
  description: z.string().optional(),
  commands: z.object({
    manifest: z.string().optional(),
    directory: z.string().optional()
  }).optional(),
  build: z.object({
    entry: z.string().or(z.array(z.string())).optional(),
    outdir: z.string().optional(),
    targets: z.array(z.string()).optional(),
    compress: z.boolean().optional(),
    external: z.array(z.string()).optional(),
    minify: z.boolean().optional(),
    sourcemap: z.boolean().optional(),
    compile: z.boolean().optional()
  }).optional(),
  // ... more options
})

Loading Configuration

Bunli automatically looks for configuration files in this order:

  1. bunli.config.ts
  2. bunli.config.js
  3. bunli.config.mjs

The configuration is loaded and validated before any CLI commands run.

Default Values

If no configuration file is found, these defaults are used:

{
  name: package.name,
  version: package.version,
  description: package.description,
  commands: {
    directory: './commands'  // REQUIRED
  },
  build: {
    entry: './cli.ts',
    outdir: './dist',
    targets: ['native'],
    compress: false,
    minify: false,
    sourcemap: true
  },
  plugins: []  // REQUIRED
}

Best Practices

  1. Keep It Simple: Start with minimal configuration
  2. Use TypeScript: Get autocomplete and type checking
  3. Environment Variables: Use for deployment-specific settings
  4. Share Common Config: Extract shared settings to separate files
  5. Document Options: Add comments for team members

See Also