The bun
CLI contains an npm
-compatible package manager designed to be a faster replacement for existing package management tools like npm
, yarn
, and pnpm
. It's designed for Node.js compatibility; use it in any Bun or Node.js project.
⚡️ 80x faster — Switch from npm install
to bun install
in any Node.js project to make your installations up to 80x faster.

For Linux users
Install dependencies
To install all dependencies of a project:
bun install
On Linux, bun install
tends to install packages 20-100x faster than npm install
. On macOS, it's more like 4-80x.
Running bun install
will:
- Install all
dependencies
,devDependencies
, andoptionalDependencies
. Bun does not installpeerDependencies
by default. - Run your project's
{pre|post}install
scripts at the appropriate time. For security reasons Bun does not execute lifecycle scripts of installed dependencies. - Write a
bun.lockb
lockfile to the project root.
To install in production mode (i.e. without devDependencies
):
bun install --production
To perform a dry run (i.e. don't actually install anything):
bun install --dry-run
To modify logging verbosity:
bun install --verbose # debug logging
bun install --silent # no logging
Configuring behavior
Add and remove packages
To add or remove a particular package:
bun add preact
bun remove preact
To specify a version, version range, or tag:
bun add zod@3.20.0
bun add zod@^3.0.0
bun add zod@latest
To add a package as a dev dependency ("devDependencies"
):
bun add --development @types/react
bun add -d @types/react
To add a package as an optional dependency ("optionalDependencies"
):
bun add --optional lodash
To install a package globally:
bun add --global cowsay # or `bun add -g cowsay`
cowsay "Bun!"
______
< Bun! >
------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
Configuring global installation behavior
To view a complete list of options for a given command:
bun add --help
Git dependencies
To add a dependency from a git repository:
bun install git@github.com:moment/moment.git
Bun supports a variety of protocols, including github
, git
, git+ssh
, git+https
, and many more.
{
"dependencies": {
"dayjs": "git+https://github.com/iamkun/dayjs.git",
"lodash": "git+ssh://github.com/lodash/lodash.git#4.17.21",
"moment": "git@github.com:moment/moment.git",
"zod": "github:colinhacks/zod"
}
}
Global cache
All packages downloaded from the registry are stored in a global cache at ~/.bun/install/cache
. They are stored in subdirectories named like ${name}@${version}
, so multiple versions of a package can be cached.
Configuring cache behavior
Minimizing re-downloads
Bun strives to avoid re-downloading packages mutiple times. When installing a package, if the cache already contains a version in the range specified by package.json
, Bun will use the cached package instead of downloading it again.
Installation details
Fast copying
Once a package is downloaded into the cache, Bun still needs to copy those files into node_modules
. Bun uses the fastest syscalls available to perform this task. On Linux, it uses hardlinks; on macOS, it uses clonefile
.
Saving disk space
Since Bun uses hardlinks to "copy" a module into a project's node_modules
directory on Linux, the contents of the package only exist in a single location on disk, greatly reducing the amount of disk space dedicated to node_modules
.
This benefit does not extend to macOS, which uses clonefile
for performance reasons.
Installation strategies
Lockfile
Running bun install
will create a binary lockfile called bun.lockb
.
Why is it binary?
In a word: Performance. Bun’s lockfile saves & loads incredibly quickly, and saves a lot more data than what is typically inside lockfiles.
How do I inspect it?
Run bun install -y
to generate a Yarn-compatible yarn.lock
(v1) that can be inspected more easily.
Platform-specific dependencies?
Bun stores normalized cpu
and os
values from npm in the lockfile, along with the resolved packages. It skips downloading, extracting, and installing packages disabled for the current target at runtime. This means the lockfile won’t change between platforms/architectures even if the packages ultimately installed do change.
What does the lockfile store?
Packages, metadata for those packages, the hoisted install order, dependencies for each package, what packages those dependencies resolved to, an integrity hash (if available), what each package was resolved to, and which version (or equivalent).
Why is it fast?
It uses linear arrays for all data. Packages are referenced by an auto-incrementing integer ID or a hash of the package name. Strings longer than 8 characters are de-duplicated. Prior to saving on disk, the lockfile is garbage-collected & made deterministic by walking the package tree and cloning the packages in dependency order.
Can I opt out?
To install without creating a lockfile:
bun install --no-save
To install a Yarn lockfile in addition to bun.lockb
.
bun install --yarn
[install.lockfile]
# whether to save a non-Bun lockfile alongside bun.lockb
# only "yarn" is supported
print = "yarn"
Configuring lockfile
Workspaces
Bun supports workspaces
in package.json
. Workspaces make it easy to develop complex software as a monorepo consisting of several independent packages.
To try it, specify a list of sub-packages in the workspaces
field of your package.json
; it's conventional to place these sub-packages in a directory called packages
.
{
"name": "my-project",
"version": "1.0.0",
"workspaces": ["packages/*"]
}
Glob support — Bun v0.5.8 added support for simple globs for workspace names, with a "*/" at the end. Nothing too fancy.
This has a couple major benefits.
- Code can be split into logical parts. If one package relies on another, you can simply add it as a dependency with
bun add
. If packageb
depends ona
,bun install
will symlink your localpackages/a
directory into thenode_modules
folder ofb
, instead of trying to download it from the npm registry. - Dependencies can be de-duplicated. If
a
andb
share a common dependency, it will be hoisted to the rootnode_modules
directory. This reduces redundant disk usage and minimizes "dependency hell" issues associated with having multiple versions of a package installed simultaneously.
⚡️ Speed — Installs are fast, even for big monorepos. Bun installs the Remix monorepo in about 500ms
on Linux.
- 28x faster than
npm install
- 12x faster than
yarn install
(v1) - 8x faster than
pnpm install

Registries
The default registry is registry.npmjs.org
. This can be globally configured in bunfig.toml
:
[install]
# set default registry as a string
registry = "https://registry.npmjs.org"
# set a token
registry = { url = "https://registry.npmjs.org", token = "123456" }
# set a username/password
registry = "https://username:password@registry.npmjs.org"
To configure a private registry scoped to a particular organization:
[install.scopes]
# registry as string
"@myorg1" = "https://username:password@registry.myorg.com/"
# registry with username/password
# you can reference environment variables
"@myorg2" = { username = "myusername", password = "$NPM_PASS", url = "https://registry.myorg.com/" }
# registry with token
"@myorg3" = { token = "$npm_token", url = "https://registry.myorg.com/" }
Linking and unlinking
Use bun link
in a local directory to register the current package as a "linkable" package.
cd /path/to/cool-pkg
cat package.json
{
"name": "cool-pkg",
"version": "1.0.0"
}
bun link
bun link v0.5.7 (7416672e)
Success! Registered "cool-pkg"
To use cool-pkg in a project, run:
bun link cool-pkg
Or add it in dependencies in your package.json file:
"cool-pkg": "link:cool-pkg"
This package can now be "linked" into other projects using bun link cool-pkg
. This will create a symlink in the node_modules
directory of the target project, pointing to the local directory.
cd /path/to/my-app
bun link cool-pkg
This will add cool-pkg
to the dependencies
field of your app's package.json with a special version specifier that tells Bun to load from the registered local directory instead of installing from npm
.
{
"name": "my-app",
"version": "1.0.0",
"dependencies": {
"cool-pkg": "link:cool-pkg"
}
}
Utilities
The bun pm
command group provides a set of utilities for working with Bun's package manager.
To print the path to the bin
directory for the local project:
bun pm bin
/path/to/current/project/node_modules/.bin
To get the path to the global bin
directory:
bun pm bin
<$HOME>/.bun/bin
To print a list of packages installed in the current project and their resolved versions, excluding their dependencies. Use the --all
flag to print the entire tree, including all nth-order dependencies.
bun pm ls
/path/to/project node_modules (5)
├── eslint@8.33.0
├── react@18.2.0
├── react-dom@18.2.0
├── typescript@4.8.4
└── zod@3.20.1
To print the path to Bun's global module cache:
bun pm cache
To clear Bun's global module cache:
bun pm cache rm