---
title: "How to set up Bun as a package manager"
slug: "set-up-bun-as-a-package-manager"
category: "howto"
tags: ["howto", "bun", "package-manager", "javascript", "node", "tooling"]
status: "stable"
last_updated: 2026-08-14
summary: "Install Bun, initialize a project, and run installs and scripts to replace npm or pnpm with Bun's faster runtime and package manager."
related: ["[[comparisons/yarn-vs-pnpm]]", "[[howto/migrate-from-npm-to-pnpm]]", "[[comparisons/swc-vs-babel]]", "[[comparisons/vite-vs-webpack]]", "[[coding/general-principles]]", "[[tooling/github]]", "[[comparisons/jest-vs-vitest]]"]
---

## Overview

Bun is a JavaScript runtime and package manager that is significantly faster than Node.js and npm for installs and script execution. Use it to replace npm, Yarn, or pnpm in projects where raw speed matters and Node.js compatibility is not a blocking constraint. This guide installs Bun, migrates a project's lock file, and verifies that scripts and tests run correctly. See [[comparisons/yarn-vs-pnpm]] for where Bun fits in the package manager landscape.

## Prerequisites

- macOS, Linux, or Windows (WSL2). Bun has experimental native Windows support.
- A `package.json`-based project. Bun is compatible with npm's registry and lock file format.
- No native modules that require Node.js's `node-gyp` compile step if targeting Bun's runtime. (Bun as a package manager works alongside Node.js; the runtime is separate.)

## Steps

### 1. Install Bun

```bash
# macOS and Linux
curl -fsSL https://bun.sh/install | bash

# Or via Homebrew
brew install oven-sh/bun/bun

# Verify
bun --version
```

The installer adds `~/.bun/bin` to your `PATH`. Restart the shell or source the profile if `bun` is not found.

### 2. Initialize or migrate a project

For a new project:

```bash
mkdir my-app && cd my-app
bun init
```

`bun init` generates a `package.json`, `tsconfig.json`, and `index.ts`.

For an existing project with an npm or pnpm lock file:

```bash
# Remove the old lock file and node_modules
rm -rf node_modules package-lock.json yarn.lock pnpm-lock.yaml

# Install with Bun; this generates bun.lock
bun install
```

`bun.lock` is a text-based, JSONC-formatted lock file (the default since Bun 1.2). Commit it to source control for reproducible installs; it diffs and merges cleanly in pull requests, unlike the older binary `bun.lockb` format. If a project still has `bun.lockb` from an older Bun version, migrate with `bun install --save-text-lockfile --frozen-lockfile --lockfile-only` and delete `bun.lockb`.

### 3. Run scripts

Bun executes `package.json` scripts with `bun run`. The `run` keyword is optional for non-ambiguous script names.

```bash
bun run build
bun run dev
bun test          # Bun's built-in test runner
```

Bun's built-in test runner is Jest-compatible. Rename test files to `.test.ts` and use `describe`, `it`, and `expect` directly; no additional package is needed.

### 4. Configure CI

Replace npm CI commands with Bun equivalents. For GitHub Actions:

```yaml
- uses: oven-sh/setup-bun@v2
  with:
    bun-version: latest

- run: bun install --frozen-lockfile
- run: bun run build
- run: bun test
```

`--frozen-lockfile` fails the install if `bun.lockb` is out of date, catching dependency drift.

### 5. Add Bun type definitions (TypeScript projects)

```bash
bun add -d @types/bun
```

This enables type-checking for `Bun.serve`, `Bun.file`, and other Bun-specific APIs when using the Bun runtime.

## Verify it worked

```bash
# Confirm Bun manages the project
bun --version
ls bun.lock                 # lock file exists

# Install and run
bun install
bun run build               # exits 0
bun test                    # all tests pass
```

If `bun test` runs and outputs test results, Bun is managing the project correctly.

## Common errors

- **`bun: command not found` after install**: `~/.bun/bin` is not on `PATH`. Add `export PATH="$HOME/.bun/bin:$PATH"` to `~/.bashrc` or `~/.zshrc`.
- **Native module fails to compile**: some packages use Node.js `node-gyp` bindings that Bun does not support. If a specific package fails, run that package under Node.js and use Bun for everything else, or switch back to npm/pnpm.
- **`bun.lock` conflicts in CI**: `bun install --frozen-lockfile` will fail if `package.json` was updated without regenerating the lock file. Run `bun install` locally and commit the new `bun.lock`.
- **`bun test` not finding test files**: Bun defaults to `**/*.test.{ts,tsx,js,jsx}`. If test files use a different naming convention, set `test.pattern` in `bunfig.toml`.
- **Workspace packages not resolving**: declare workspaces in `package.json` under `workspaces`. Bun supports npm-style workspaces.

## Related

- [[comparisons/yarn-vs-pnpm]]
- [[howto/migrate-from-npm-to-pnpm]]
- [[comparisons/swc-vs-babel]]
- [[comparisons/vite-vs-webpack]]
- [[coding/general-principles]]
- [[tooling/github]]
- [[comparisons/jest-vs-vitest]]
