Bunli
Packages

bunli

CLI toolchain for developing, building, testing, and distributing Bunli applications

Installation

bash bun add -g bunli

Features

  • ๐Ÿš€ Development Mode - Hot reload with Bun's --hot flag
  • ๐Ÿ—๏ธ Build System - Create standalone executables or traditional JS builds
  • ๐Ÿงช Test Runner - Integrated testing with coverage support
  • ๐Ÿ“ฆ Release Automation - Version bumping, git tags, and npm publishing
  • ๐ŸŽฏ Multi-Platform - Build for macOS, Linux, and Windows from any platform
  • โš™๏ธ Configuration - Flexible bunli.config.ts system
  • ๐Ÿ” Debugging - Built-in debugger support
  • ๐Ÿ“ Workspace Support - Monorepo-friendly commands
  • ๐Ÿš Shell UI - Terminal components for scripts and workflows
  • ๐Ÿ”ง Diagnostics - Built-in doctor command for troubleshooting

Commands

bunli init

Initialize a new Bunli CLI project. This is an alias for create-bunli.

bunli init my-cli
cd my-cli

Options:

  • --name, -n - Project name
  • --template, -t - Project template (basic, advanced, monorepo)
  • --dir, -d - Directory to create project in
  • --git, -g - Initialize git repository (default: true)
  • --install - Install dependencies (default: true)
  • --package-manager, -p - Package manager to use (bun, pnpm, yarn, npm)

bunli dev

Run your CLI in development mode with hot reload.

bunli dev
# alias: bunli d

Options:

  • --entry, -e - Entry file (defaults to auto-detect)
  • --generate - Enable codegen (default: true)
  • --clearScreen - Clear screen on reload (default: true)
  • --watch, -w - Watch for changes (default: true)
  • --inspect, -i - Enable debugger
  • --port, -p - Debugger port (default: 9229)

Features:

  • Automatic hot reload with Bun's --hot flag
  • Automatic type generation when code changes
  • Debugger support for breakpoint debugging
  • Auto-detection of entry point from package.json or common patterns
  • Pass-through arguments to your CLI

Example:

# Run with debugger
bunli dev --inspect

# Run with custom entry and arguments
bunli dev --entry src/cli.ts -- --verbose

# Disable watch mode
bunli dev --watch false

# Disable codegen
bunli dev --generate false

bunli build

Build your CLI for production, either as standalone executables or traditional JavaScript.

bunli build
# alias: bunli b

Options:

  • --entry, -e - Entry file (defaults to auto-detect)
  • --outdir, -o - Output directory (default: ./dist)
  • --outfile - Output filename (for single executable)
  • --targets, -t - Target platforms for compilation (comma-separated)
  • --minify, -m - Minify output
  • --sourcemap, -s - Generate sourcemaps
  • --bytecode - Enable bytecode compilation (experimental)
  • --runtime, -r - Runtime target (bun, node)
  • --watch, -w - Watch for changes

Target Platforms:

  • native - Current platform only
  • darwin-arm64 - macOS Apple Silicon
  • darwin-x64 - macOS Intel
  • linux-arm64 - Linux ARM64
  • linux-x64 - Linux x64
  • windows-x64 - Windows x64
  • all - All supported platforms

Examples:

# Build traditional JS (requires Bun runtime)
bunli build

# Build standalone executable for current platform
bunli build --targets native

# Build for specific platforms
bunli build --targets darwin-arm64,linux-x64

# Build for all platforms
bunli build --targets all

# Custom output directory
bunli build --outdir ./bin

# Watch mode
bunli build --watch

bunli generate

Generate TypeScript type definitions for your commands.

bunli generate
# alias: bunli gen

Options:

  • --entry, -e - CLI entry file used for command discovery
  • --directory - Optional fallback command source directory
  • --output, -o - Output file (default: ./.bunli/commands.gen.ts)
  • --watch, -w - Watch for changes and regenerate

Examples:

# Generate types once
bunli generate

# Generate with custom output location
bunli generate --output ./types/commands.ts

# Watch for changes
bunli generate --watch

# Use explicit entry
bunli generate --entry ./src/cli.ts

# Optional fallback directory
bunli generate --directory ./src/commands

Type generation is automatically run during bunli dev and bunli build. You typically only need to run this manually for one-off generation or when using watch mode.

bunli test

Run tests for your CLI using Bun's native test runner.

bunli test
# alias: bunli t

Options:

  • --pattern, -p - Test file patterns (default: **/*.test.ts); can be specified multiple times
  • --watch, -w - Watch for changes
  • --coverage, -c - Generate coverage report
  • --bail, -b - Stop on first failure
  • --timeout - Test timeout in milliseconds
  • --all - Run tests in all packages (workspace mode)

Examples:

# Run all tests
bunli test

# Run with coverage
bunli test --coverage

# Run specific test files
bunli test --pattern "src/**/*.test.ts"

# Run tests in all workspace packages
bunli test --all

# Watch mode for TDD
bunli test --watch

bunli release

Create a release of your CLI with automated version bumping, git tagging, and publishing.

bunli release
# alias: bunli r

Options:

  • --version, -V - Version to release (patch, minor, major, or x.y.z)
  • --tag, -t - Git tag format (default: v{{version}})
  • --npm - Publish to npm
  • --github - Create GitHub release
  • --resume - Resume from unfinished release state (default: true)
  • --dry, -d - Dry run - show what would be done without making changes

Features:

  • Interactive version selection
  • Automated version bumping following semver
  • Git tag creation and pushing
  • npm publishing with proper build step
  • GitHub release creation (notes only; no build artifacts)
  • Resume support for interrupted releases
  • Dry run mode for testing

Examples:

# Interactive release
bunli release

# Specific version bump
bunli release --version patch

# Major version with GitHub release
bunli release --version major --github

# Dry run to preview changes
bunli release --dry

# Skip npm publish
bunli release --npm=false

# Skip GitHub release
bunli release --github=false

# Don't resume from previous state
bunli release --resume=false

Use --npm=false (not --no-npm) to disable npm publishing. Boolean options work as --flag (true) or --flag=false (false).

bunli doctor

Run diagnostics for Bunli projects to identify and fix common issues.

bunli doctor

Subcommands:

bunli doctor completions

Check shell completion setup and fix issues.

bunli doctor completions

Options:

  • --shell - Target shell (bash, zsh, fish, powershell)

Examples:

# Check all shell completions
bunli doctor completions

# Fix zsh completions
bunli doctor completions --shell zsh

# Fix fish completions
bunli doctor completions --shell fish

bunli shell

Shell UI helpers for scripts and terminal workflows. A group of 12 commands for building interactive terminal experiences.

bunli shell <subcommand>

bunli shell confirm

Ask a yes/no question.

bunli shell confirm "Continue with deployment?"

Options:

  • --default - Default value (default: false)
  • --affirmative - Affirmative label (default: "Yes")
  • --negative - Negative label (default: "No")
  • --timeout, -t - Timeout in seconds

bunli shell choose

Choose from a list of options.

bunli shell choose Option1 Option2 Option3
# Or pipe via stdin:
echo -e "Option1\nOption2\nOption3" | bunli shell choose

Options:

  • --multiple - Allow multiple selections
  • --limit - Max selections
  • --height - Visible items (default: 10)
  • --ordered - Maintain selection order

bunli shell input

Prompt for single-line text input.

bunli shell input "Enter your name:"

Options:

  • --placeholder - Placeholder text
  • --prompt - Prompt message
  • --value - Default value
  • --char-limit - Character limit

bunli shell spin

Run a command with a spinner.

bunli shell spin "Building..." -- bun run build

Options:

  • --title - Spinner title (default: "Loading...")

bunli shell pager

View content in a scrollable pager.

bunli shell pager --file README.md
# Or pipe via stdin:
cat README.md | bunli shell pager

Options:

  • --file, -f - File to display

bunli shell filter

Filter lines from stdin.

echo -e "foo\nbar\nbaz" | bunli shell filter "b*"

bunli shell file

Interactive file picker.

bunli shell file

bunli shell style

Apply ANSI styling to text.

bunli shell style --bold "Important text"

bunli shell join

Join lines with a delimiter.

echo -e "a\nb\nc" | bunli shell join ", "
# Output: a, b, c

bunli shell write

Write stdin to a file.

echo "content" | bunli shell write output.txt

bunli shell format

Format JSON or plain text.

echo '{"a":1}' | bunli shell format json

bunli shell log

Structured logging output.

bunli shell log --level info "Server started"

Configuration

Create a bunli.config.ts file in your project root to configure the CLI behavior:

import { defineConfig } from "@bunli/core";

export default defineConfig({
  name: "my-cli",
  version: "1.0.0",
  description: "My awesome CLI",

  // Command configuration
  commands: {
    entry: "./src/cli.ts",
    directory: "./src/commands",
  },

  // Build configuration
  build: {
    entry: "./src/cli.ts",
    outdir: "./dist",
    targets: ["darwin-arm64", "linux-x64", "windows-x64"],
    compress: true,
    external: ["@aws-sdk/*"],
    minify: true,
    sourcemap: false,
  },

  // Development configuration
  dev: {
    watch: true,
    inspect: false,
    port: 9229,
  },

  // Test configuration
  test: {
    pattern: ["**/*.test.ts", "**/*.spec.ts"],
    coverage: false,
    watch: false,
  },

  // Release configuration
  release: {
    npm: true,
    github: true,
    tagFormat: "v{{version}}",
    conventionalCommits: true,
    binary: {
      packageNameFormat: "{{name}}-{{platform}}",
      shimPath: "bin/run.mjs",
    },
  },

  // Workspace configuration (monorepos)
  workspace: {
    packages: ["packages/*"],
    versionStrategy: "independent",
  },
});

Entry Point Detection

The CLI automatically detects your entry point in this order:

  1. --entry flag
  2. build.entry in bunli.config.ts
  3. bin field in package.json
  4. Common patterns:
    • src/cli.ts
    • src/index.ts
    • src/main.ts
    • cli.ts
    • index.ts
    • main.ts

Standalone Executables

Build standalone executables that bundle your CLI with the Bun runtime:

# Build for current platform
bunli build --targets native

# Build for all platforms
bunli build --targets all

# Build for specific platforms
bunli build --targets darwin-arm64,linux-x64,windows-x64

Output structure:

dist/
โ”œโ”€โ”€ darwin-arm64/
โ”‚   โ””โ”€โ”€ my-cli
โ”œโ”€โ”€ darwin-x64/
โ”‚   โ””โ”€โ”€ my-cli
โ”œโ”€โ”€ linux-x64/
โ”‚   โ””โ”€โ”€ my-cli
โ””โ”€โ”€ windows-x64/
    โ””โ”€โ”€ my-cli.exe

With compression enabled:

dist/
โ”œโ”€โ”€ darwin-arm64.tar.gz
โ”œโ”€โ”€ darwin-x64.tar.gz
โ”œโ”€โ”€ linux-x64.tar.gz
โ””โ”€โ”€ windows-x64.tar.gz

Workspace Support

For monorepos, the CLI supports workspace-aware commands:

# Run tests in all packages
bunli test --all

# Build for all platforms (single package)
bunli build --targets all

# Workspace release mode is currently not implemented
# bunli release --all

# Run dev in specific package
cd packages/my-package && bunli dev

Environment Variables

The CLI sets these environment variables:

  • NODE_ENV - Set to development in dev mode, test in test mode, production in build mode
  • BUNLI_VERSION - The version of the bunli CLI
  • Standard Bun environment variables

Advanced Usage

Debug Mode

Enable debugging for your CLI during development:

# Start with debugger
bunli dev --inspect

# Custom debugger port
bunli dev --inspect --port 9230

Then attach your debugger (VS Code, Chrome DevTools, etc.) to the specified port.

Custom Build Pipeline

Extend the build process with pre/post hooks:

// bunli.config.ts
export default defineConfig({
  build: {
    onBeforeBuild: async () => {
      // Generate types, clean directories, etc.
    },
    onAfterBuild: async (result) => {
      // Copy additional files, generate docs, etc.
    },
  },
});

Cross-Platform Considerations

When building for multiple platforms:

// bunli.config.ts
export default defineConfig({
  build: {
    targets: ["darwin-arm64", "linux-x64", "windows-x64"],
    external: process.platform === "win32" ? ["node-pty"] : ["windows-specific-module"],
  },
});

Continuous Integration

Example GitHub Actions workflows:

CI (build + test):

name: Build and Test

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: oven-sh/setup-bun@v1

      - name: Install dependencies
        run: bun install

      - name: Run tests
        run: bunli test --coverage

      - name: Build for all platforms
        run: bunli build --targets all

bunli build can optionally compress multi-target builds into dist/&lt;target&gt;.tar.gz. For stable, release-ready archives and checksums, use bunli-releaser.

Release (binaries + checksums + Homebrew via bunli-releaser):

name: Release

on:
  push:
    tags:
      - "v*.*.*"

permissions:
  contents: write

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: AryaLabsHQ/bunli-releaser@v1
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          # Optional Homebrew update:
          # brew-tap: <owner>/<homebrew-tap>
          # brew-token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
          # brew-pr: "true"
          # existing-assets: "fail" # or "skip"

If you're using bunli-releaser, keep build.compress disabled in bunli.config.ts.

Troubleshooting

Command not found: If bunli is not found after installation, ensure your global bin directory is in PATH. Alternatively, use bunx bunli to run without global installation.

Common Issues

Build fails with module errors:

  • Check that all dependencies are installed
  • Verify entry point exists
  • Use --external for native modules
  • Check TypeScript configuration

Hot reload not working:

  • Ensure you're using bunli dev
  • Check that Bun version supports --hot
  • Some file changes may require manual restart

Tests not found:

  • Verify test file pattern matches your test files
  • Default pattern is **/*.test.ts
  • Use --pattern to specify custom patterns

Shell completions not working:

  • Run bunli doctor completions to diagnose
  • Ensure your shell is configured to source completion scripts
  • Restart your shell after installing completions

API Reference

CLI Options

All commands support these global options:

  • --help, -h - Show help for command
  • --version, -v - Show CLI version
  • --config, -c - Path to config file (default: ./bunli.config.ts)
  • --verbose - Enable verbose logging
  • --quiet, -q - Suppress non-error output

Configuration Schema

The configuration is validated using Zod. See the Configuration guide for the complete schema.

See Also

On this page