Skip to main content

Function signature

packages/core/src/cli.ts
export async function createCLI<
  TPlugins extends readonly BunliPlugin[] = []
>(
  configOverride?: BunliConfigInput & {
    plugins?: TPlugins 
    generated?: string | boolean
  },
  runtimeDeps: CreateCLIRuntimeDeps = {}
): Promise<CLI<MergeStores<TPlugins>>>
Creates a CLI instance that manages commands, configuration, and plugins. The function auto-loads configuration from bunli.config.ts, applies defaults, and initializes the plugin system.

Parameters

configOverride
BunliConfigInput & { plugins?: TPlugins; generated?: string | boolean }
Optional configuration to override or merge with loaded config. If no config file exists, name and version are required.
runtimeDeps
CreateCLIRuntimeDeps
default:"{}"
Internal runtime dependencies for testing and customization.

Return value

CLI
CLI<MergeStores<TPlugins>>
A CLI instance with methods to register commands and execute the CLI.

Configuration loading

The function automatically searches for configuration files in this order:
  1. bunli.config.ts
  2. bunli.config.js
  3. bunli.config.mjs
If a config file is found, it’s loaded and merged with configOverride. If no config file exists and configOverride doesn’t provide name and version, an error is thrown.

Generated types

The function attempts to load generated types from ./.bunli/commands.gen.ts. This enables type-safe command execution via the execute() method.

Error handling

InvalidConfigError
TaggedError
Thrown when configuration validation fails

Examples

Basic usage with config file

import { createCLI } from '@bunli/core'

const cli = await createCLI()

// Register commands
cli.command(myCommand)

// Run the CLI
await cli.run()

Usage without config file

import { createCLI } from '@bunli/core'

const cli = await createCLI({
  name: 'my-cli',
  version: '1.0.0',
  description: 'My awesome CLI tool'
})

cli.command(myCommand)
await cli.run()

With plugins

import { createCLI } from '@bunli/core'
import { completionsPlugin } from '@bunli/plugin-completions'

const cli = await createCLI({
  name: 'my-cli',
  version: '1.0.0',
  plugins: [completionsPlugin()]
})

cli.command(myCommand)
await cli.run()

Programmatic execution

import { createCLI } from '@bunli/core'

const cli = await createCLI({
  name: 'my-cli',
  version: '1.0.0'
})

cli.command(myCommand)

// Execute a command programmatically
await cli.execute('my-command', ['arg1', 'arg2'])

// Execute with options
await cli.execute('my-command', { verbose: true, output: 'json' })

// Execute with both args and options
await cli.execute('my-command', ['arg1'], { verbose: true })

Build docs developers (and LLMs) love