Architecture Decisions

ADR-0004: Bun as Package Manager

Decision to use Bun as the package manager for fast installs and modern tooling

Status

Accepted

Date: 2025-02-03

Context

Our monorepo requires a fast, reliable package manager to handle:

  • Workspace dependencies between apps and packages
  • Large dependency trees (Next.js, React, Radix UI, etc.)
  • Frequent installs during development and CI/CD
  • Lock file management for reproducible builds
  • Script execution for build, dev, and test commands

Key requirements:

  • Fast install times (developer productivity)
  • Reliable workspace support (monorepo requirement)
  • Good TypeScript tooling (we are TypeScript-first)
  • Active maintenance and community
  • Compatible with deployment targets

Decision

We chose Bun (v1.3.8+) as our package manager for the entire monorepo.

Why Bun?

  1. Speed: 10-20x faster installs than npm/yarn
  2. Native workspace support: First-class monorepo support
  3. Drop-in replacement: Uses package.json and lockfile like npm
  4. All-in-one tool: Package manager + bundler + test runner + runtime
  5. Excellent TypeScript support: Built for modern JS/TS workflows

Configuration:

{
  "packageManager": "bun@1.3.8",
  "engines": {
    "node": ">=22.0.0",
    "bun": ">=1.1.0"
  }
}

Usage:

# Install dependencies
bun install

# Add a dependency
bun add <package>

# Run scripts
bun run dev
bun run build

# Workspaces
bun add <package> --workspace=@hn-monorepo/ui

Consequences

Positive

  • Blazing fast installs: ~2-5 seconds for full install (vs 30-60s with npm)
  • Faster CI/CD: Less time waiting for dependency installation
  • Less disk usage: Hardlinks save ~50% disk space vs npm
  • Better DX: Fast feedback loop during development
  • Unified tooling: Can use Bun for testing and bundling later
  • Modern by default: Optimized for ESM, TypeScript, latest standards
  • Great monorepo support: workspace:* protocol works seamlessly
  • Active development: Bun is rapidly improving and well-maintained

Negative

  • Newer ecosystem: Less mature than npm/pnpm (released 2022)
  • Occasional compatibility issues: Some packages assume npm/pnpm behavior
  • Learning curve: Team must learn Bun-specific commands
  • CI/CD setup: Need to install Bun in CI (not pre-installed everywhere)
  • Lock file churn: bun.lockb is binary, harder to review in PRs

Neutral

  • Lock file format: Uses binary bun.lockb (faster but not human-readable)
  • Node compatibility: Bun runtime is Node-compatible but not 100% identical
  • Package resolution: Slightly different algorithm than npm (usually better)

Alternatives Considered

Alternative 1: npm (default)

  • Description: Node.js’s built-in package manager
  • Pros: Ubiquitous, no installation needed; largest community; best compatibility
  • Cons: Slow install times (~30-60s); poor monorepo performance; less efficient disk usage
  • Why not chosen: Too slow for our development velocity

Alternative 2: pnpm

  • Description: Fast, disk-efficient package manager with great monorepo support
  • Pros: Fast installs via symlinks + content-addressed storage; excellent monorepo support; strict dependency resolution
  • Cons: More complex setup than npm; symlink structure can confuse some tools; slightly slower than Bun
  • Why not chosen: Bun is faster and we do not need pnpm’s strictness (yet)

Alternative 3: Yarn (Classic or Berry)

  • Description: Facebook’s package manager (Classic = v1, Berry = v2+)
  • Pros: Yarn Classic is stable and widely used; Yarn Berry has fast, zero-installs with PnP
  • Cons: Yarn Classic is slow and deprecated; Yarn Berry is complex with a steep learning curve and PnP breaks many tools
  • Why not chosen: Bun is faster and simpler than Berry, more modern than Classic

References

Notes

  • Installation: Developers must install Bun locally (curl -fsSL https://bun.sh/install | bash)
  • CI/CD: GitHub Actions use oven-sh/setup-bun@v1 to install Bun
  • Compatibility: If a package does not work with Bun, we can fall back to npm for that specific command
  • Lock file: Committed bun.lockb ensures reproducible builds across team and CI
  • Rollback plan: If Bun causes issues, we can switch to pnpm with minimal changes (both support workspace:* protocol)
HanseNexus 2026