Wβ
All docs
π
Sign Up/Sign In
bun.sh/docs/install/
Public Link
Apr 8, 2025, 12:51:22 PM - complete - 22.8 kB
Starting URLs:
https://bun.sh/docs
Crawl Prefixes:
https://bun.sh/docs/install/
## Page: https://bun.sh/docs Bun is an all-in-one toolkit for JavaScript and TypeScript apps. It ships as a single executable called `bun`. At its core is the _Bun runtime_, a fast JavaScript runtime designed as **a drop-in replacement for Node.js**. It's written in Zig and powered by JavaScriptCore under the hood, dramatically reducing startup times and memory usage. bun run index.tsx # TS and JSX supported out of the box The `bun` command-line tool also implements a test runner, script runner, and Node.js-compatible package manager, all significantly faster than existing tools and usable in existing Node.js projects with little to no changes necessary. bun run start # run the `start` script bun install <pkg> # install a package bun build ./index.tsx # bundle a project for browsers bun test # run tests bunx cowsay 'Hello, world!' # execute a package Get started with one of the quick links below, or read on to learn more about Bun. ## What is a runtime? JavaScript (or, more formally, ECMAScript) is just a _specification_ for a programming language. Anyone can write a JavaScript _engine_ that ingests a valid JavaScript program and executes it. The two most popular engines in use today are V8 (developed by Google) and JavaScriptCore (developed by Apple). Both are open source. But most JavaScript programs don't run in a vacuum. They need a way to access the outside world to perform useful tasks. This is where _runtimes_ come in. They implement additional APIs that are then made available to the JavaScript programs they execute. ### Browsers Notably, browsers ship with JavaScript runtimes that implement a set of Web-specific APIs that are exposed via the global `window` object. Any JavaScript code executed by the browser can use these APIs to implement interactive or dynamic behavior in the context of the current webpage. ### Node.js Similarly, Node.js is a JavaScript runtime that can be used in non-browser environments, like servers. JavaScript programs executed by Node.js have access to a set of Node.js-specific globals like `Buffer`, `process`, and `__dirname` in addition to built-in modules for performing OS-level tasks like reading/writing files (`node:fs`) and networking (`node:net`, `node:http`). Node.js also implements a CommonJS-based module system and resolution algorithm that pre-dates JavaScript's native module system. Bun is designed as a faster, leaner, more modern replacement for Node.js. ## Design goals Bun is designed from the ground-up with today's JavaScript ecosystem in mind. * **Speed**. Bun processes start 4x faster than Node.js currently (try it yourself!) * **TypeScript & JSX support**. You can directly execute `.jsx`, `.ts`, and `.tsx` files; Bun's transpiler converts these to vanilla JavaScript before execution. * **ESM & CommonJS compatibility**. The world is moving towards ES modules (ESM), but millions of packages on npm still require CommonJS. Bun recommends ES modules, but supports CommonJS. * **Web-standard APIs**. Bun implements standard Web APIs like `fetch`, `WebSocket`, and `ReadableStream`. Bun is powered by the JavaScriptCore engine, which is developed by Apple for Safari, so some APIs like `Headers` and `URL` directly use Safari's implementation. * **Node.js compatibility**. In addition to supporting Node-style module resolution, Bun aims for full compatibility with built-in Node.js globals (`process`, `Buffer`) and modules (`path`, `fs`, `http`, etc.) _This is an ongoing effort that is not complete._ Refer to the compatibility page for the current status. Bun is more than a runtime. The long-term goal is to be a cohesive, infrastructural toolkit for building apps with JavaScript/TypeScript, including a package manager, transpiler, bundler, script runner, test runner, and more. --- ## Page: https://bun.sh/docs/install/cache All packages downloaded from the registry are stored in a global cache at `~/.bun/install/cache`, or the path defined by the environment variable `BUN_INSTALL_CACHE_DIR`. They are stored in subdirectories named like `${name}@${version}`, so multiple versions of a package can be cached. Configuring cache behavior (bunfig.toml) ## Minimizing re-downloads Bun strives to avoid re-downloading packages multiple 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 and Windows, 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 also applies to macOS, but there are exceptions. It uses `clonefile` which is copy-on-write, meaning it will not occupy disk space, but it will count towards drive's limit. This behavior is useful if something attempts to patch `node_modules/*`, so it's impossible to affect other installations. Installation strategies --- ## Page: https://bun.sh/docs/install/workspaces Bun supports `workspaces` in `package.json`. Workspaces make it easy to develop complex software as a _monorepo_ consisting of several independent packages. It's common for a monorepo to have the following structure: tree <root> βββ README.md βββ bun.lock βββ package.json βββ tsconfig.json βββ packages Β Β βββ pkg-a Β Β βΒ Β βββ index.ts Β Β βΒ Β βββ package.json Β Β βΒ Β βββ tsconfig.json Β Β βββ pkg-b Β Β βΒ Β βββ index.ts Β Β βΒ Β βββ package.json Β Β βΒ Β βββ tsconfig.json Β Β βββ pkg-c Β Β βββ index.ts Β Β βββ package.json Β Β βββ tsconfig.json In the root `package.json`, the `"workspaces"` key is used to indicate which subdirectories should be considered packages/workspaces within the monorepo. It's conventional to place all the workspace in a directory called `packages`. { "name": "my-project", "version": "1.0.0", "workspaces": ["packages/*"], "devDependencies": { "example-package-in-monorepo": "workspace:*" } } **Glob support** β Bun supports full glob syntax in `"workspaces"` (see here for a comprehensive list of supported syntax), _except_ for exclusions (e.g. `!**/excluded/**`), which are not implemented yet. Each workspace has it's own `package.json`. When referencing other packages in the monorepo, semver or workspace protocols (e.g. `workspace:*`) can be used as the version field in your `package.json`. { "name": "pkg-a", "version": "1.0.0", "dependencies": { "pkg-b": "workspace:*" } } `bun install` will install dependencies for all workspaces in the monorepo, de-duplicating packages if possible. If you only want to install dependencies for specific workspaces, you can use the `--filter` flag. # Install dependencies for all workspaces starting with `pkg-` except for `pkg-c` bun install --filter "pkg-*" --filter "!pkg-c" # Paths can also be used. This is equivalent to the command above. bun install --filter "./packages/pkg-*" --filter "!pkg-c" # or --filter "!./packages/pkg-c" When publishing, `workspace:` versions are replaced by the package's `package.json` version, "workspace:*" -> "1.0.1" "workspace:^" -> "^1.0.1" "workspace:~" -> "~1.0.1" Setting a specific version takes precedence over the package's `package.json` version, "workspace:1.0.2" -> "1.0.2" // Even if current version is 1.0.1 Workspaces have 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 in `package.json`. If package `b` depends on `a`, `bun install` will install your local `packages/a` directory into `node_modules` instead of downloading it from the npm registry. * **Dependencies can be de-duplicated.** If `a` and `b` share a common dependency, it will be _hoisted_ to the root `node_modules` directory. This reduces redundant disk usage and minimizes "dependency hell" issues associated with having multiple versions of a package installed simultaneously. * **Run scripts in multiple packages.** You can use the `--filter` flag to easily run `package.json` scripts in multiple packages in your workspace. β‘οΈ **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`  --- ## Page: https://bun.sh/docs/install/lifecycle Packages on `npm` can define _lifecycle scripts_ in their `package.json`. Some of the most common are below, but there are many others. * `preinstall`: Runs before the package is installed * `postinstall`: Runs after the package is installed * `preuninstall`: Runs before the package is uninstalled * `prepublishOnly`: Runs before the package is published These scripts are arbitrary shell commands that the package manager is expected to read and execute at the appropriate time. But executing arbitrary scripts represents a potential security risk, soβunlike other `npm` clientsβBun does not execute arbitrary lifecycle scripts by default. ## `postinstall` The `postinstall` script is particularly important. It's widely used to build or install platform-specific binaries for packages that are implemented as native Node.js add-ons. For example, `node-sass` is a popular package that uses `postinstall` to build a native binary for Sass. { "name": "my-app", "version": "1.0.0", "dependencies": { "node-sass": "^6.0.1" } } ## `trustedDependencies` Instead of executing arbitrary scripts, Bun uses a "default-secure" approach. You can add certain packages to an allow list, and Bun will execute lifecycle scripts for those packages. To tell Bun to allow lifecycle scripts for a particular package, add the package name to `trustedDependencies` array in your `package.json`. { "name": "my-app", "version": "1.0.0", "trustedDependencies": ["node-sass"] } Once added to `trustedDependencies`, install/re-install the package. Bun will read this field and run lifecycle scripts for `my-trusted-package`. As of Bun v1.0.16, the top 500 npm packages with lifecycle scripts are allowed by default. You can see the full list here. ## `--ignore-scripts` To disable lifecycle scripts for all packages, use the `--ignore-scripts` flag. bun install --ignore-scripts --- ## Page: https://bun.sh/docs/install/lockfile Running `bun install` will create a lockfile called `bun.lock`. #### Should it be committed to git? Yes #### Generate a lockfile without installing? To generate a lockfile without installing to `node_modules` you can use the `--lockfile-only` flag. The lockfile will always be saved to disk, even if it is up-to-date with the `package.json`(s) for your project. bun install --lockfile-only **Note** - using `--lockfile-only` will still populate the global install cache with registry metadata and git/tarball dependencies. #### Can I opt out? To install without creating a lockfile: bun install --no-save To install a Yarn lockfile _in addition_ to `bun.lock`. CLIΒ flag bun install --yarn bunfig.toml [install.lockfile] # whether to save a non-Bun lockfile alongside bun.lock # only "yarn" is supported print = "yarn" #### Text-based lockfile Bun v1.2 changed the default lockfile format to the text-based `bun.lock`. Existing binary `bun.lockb` lockfiles can be migrated to the new format by running `bun install --save-text-lockfile --frozen-lockfile --lockfile-only` and deleting `bun.lockb`. More information about the new lockfile format can be found on our blogpost. --- ## Page: https://bun.sh/docs/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/" } ### `.npmrc` Bun also reads `.npmrc` files, learn more. --- ## Page: https://bun.sh/docs/install/overrides Bun supports npm's `"overrides"` and Yarn's `"resolutions"` in `package.json`. These are mechanisms for specifying a version range for _metadependencies_βthe dependencies of your dependencies. package.json { "name": "my-app", "dependencies": { "foo": "^2.0.0" }, "overrides": { "bar": "~4.4.0" } } By default, Bun will install the latest version of all dependencies and metadependencies, according to the ranges specified in each package's `package.json`. Let's say you have a project with one dependency, `foo`, which in turn has a dependency on `bar`. This means `bar` is a _metadependency_ of our project. package.json { "name": "my-app", "dependencies": { "foo": "^2.0.0" } } When you run `bun install`, Bun will install the latest versions of each package. # tree layout of node_modules node_modules βββ foo@1.2.3 βββ bar@4.5.6 But what if a security vulnerability was introduced in `bar@4.5.6`? We may want a way to pin `bar` to an older version that doesn't have the vulnerability. This is where `"overrides"`/`"resolutions"` come in. ## `"overrides"` Add `bar` to the `"overrides"` field in `package.json`. Bun will defer to the specified version range when determining which version of `bar` to install, whether it's a dependency or a metadependency. **Note** β Bun currently only supports top-level `"overrides"`. Nested overrides are not supported. package.json { "name": "my-app", "dependencies": { "foo": "^2.0.0" }, "overrides": { "bar": "~4.4.0" } } ## `"resolutions"` The syntax is similar for `"resolutions"`, which is Yarn's alternative to `"overrides"`. Bun supports this feature to make migration from Yarn easier. As with `"overrides"`, _nested resolutions_ are not currently supported. package.json { "name": "my-app", "dependencies": { "foo": "^2.0.0" }, "resolutions": { "bar": "~4.4.0" } } --- ## Page: https://bun.sh/docs/install/patch `bun patch` lets you persistently patch node\_modules in a maintainable, git-friendly way. Sometimes, you need to make a small change to a package in `node_modules/` to fix a bug or add a feature. `bun patch` makes it easy to do this without vendoring the entire package and reuse the patch across multiple installs, multiple projects, and multiple machines. Features: * Generates `.patch` files applied to dependencies in `node_modules` on install * `.patch` files can be committed to your repository, reused across multiple installs, projects, and machines * `"patchedDependencies"` in `package.json` keeps track of patched packages * `bun patch` lets you patch packages in `node_modules/` while preserving the integrity of Bun's Global Cache * Test your changes locally before committing them with `bun patch --commit <pkg>` * To preserve disk space and keep `bun install` fast, patched packages are committed to the Global Cache and shared across projects where possible #### Step 1. Prepare the package for patching To get started, use `bun patch <pkg>` to prepare the package for patching: # you can supply the package name bun patch react # ...and a precise version in case multiple versions are installed bun patch react@17.0.2 # or the path to the package bun patch node_modules/react **Note** β Don't forget to call `bun patch <pkg>`! This ensures the package folder in `node_modules/` contains a fresh copy of the package with no symlinks/hardlinks to Bun's cache. If you forget to do this, you might end up editing the package globally in the cache! #### Step 2. Test your changes locally `bun patch <pkg>` makes it safe to edit the `<pkg>` in `node_modules/` directly, while preserving the integrity of Bun's Global Cache. This works by re-creating an unlinked clone of the package in `node_modules/` and diffing it against the original package in the Global Cache. #### Step 3. Commit your changes Once you're happy with your changes, run `bun patch --commit <path or pkg>`. Bun will generate a patch file in `patches/`, update your `package.json` and lockfile, and Bun will start using the patched package: # you can supply the path to the patched package bun patch --commit node_modules/react # ... or the package name and optionally the version bun patch --commit react@17.0.2 # choose the directory to store the patch files bun patch --commit react --patches-dir=mypatches # `patch-commit` is available for compatibility with pnpm bun patch-commit react ## CLI Usage $bun patch <package>@<version> flags or options ### Flags #### Configuration \-c,\--config\=<val> Specify path to config file (bunfig.toml) \--registry\=<val> Use a specific registry by default, overriding .npmrc, bunfig.toml and environment variables #### Dependency Management \-y,\--yarn Write a yarn.lock file (yarn v1) \-p,\--production Don't install devDependencies \--no-save Don't update package.json or save a lockfile \--save Save to package.json (true by default) \--omit\=<val> Exclude 'dev', 'optional', or 'peer' dependencies from install #### Lockfile Management \--frozen-lockfile Disallow changes to lockfile \--save-text-lockfile Save a text-based lockfile \--lockfile-only Generate a lockfile without installing dependencies #### Installation Behavior \-f,\--force Always request the latest versions from the registry & reinstall all dependencies \--dry-run Don't install anything \--ignore-scripts Skip lifecycle scripts in the project's package.json (dependency scripts are never run) \--trust Add to trustedDependencies in the project's package.json and install the package(s) #### Caching and Performance \--cache-dir\=<val> Store & load cached data from a specific directory path \--no-cache Ignore manifest cache entirely \--concurrent-scripts\=<val> Maximum number of concurrent jobs for lifecycle scripts (default 5) \--network-concurrency\=<val> Maximum number of concurrent network requests (default 48) \--backend\=<val> Platform-specific optimizations for installing dependencies. Possible values: "clonefile" (default), "hardlink", "symlink", "copyfile" #### Logging and Output \--silent Don't log anything \--verbose Excessively verbose logging \--no-progress Disable the progress bar \--no-summary Don't print a summary #### Security and Verification \--ca\=<val> Provide a Certificate Authority signing certificate \--cafile\=<val> The same as \`--ca\`, but is a file path to the certificate \--no-verify Skip verifying integrity of newly downloaded packages #### Utility \-g,\--global Install globally \--cwd\=<val> Set a specific cwd \-h,\--help Print this help menu #### Patching \--commit Install a package containing modifications in \`dir\` \--patches-dir\=<val> The directory to put the patch file in (only if --commit is used) --- ## Page: https://bun.sh/docs/install/npmrc Bun supports loading configuration options from `.npmrc` files, allowing you to reuse existing registry/scope configurations. **NOTE**: We recommend migrating your `.npmrc` file to Bun's `bunfig.toml` format, as it provides more flexible options and can let you configure Bun-specific options. ## Supported options ### `registry`: Set the default registry The default registry is used to resolve packages, its default value is `npm`'s official registry (`https://registry.npmjs.org/`). To change it, you can set the `registry` option in `.npmrc`: registry=http://localhost:4873/ The equivalent `bunfig.toml` option is `install.registry`: install.registry = "http://localhost:4873/" ### `@<scope>:registry`: Set the registry for a specific scope Allows you to set the registry for a specific scope: @myorg:registry=http://localhost:4873/ The equivalent `bunfig.toml` option is to add a key in `install.scopes`: [install.scopes] myorg = "http://localhost:4873/" ### `//<registry_url>/:<key>=<value>`: Configure options for a specific registry Allows you to set options for a specific registry: # set an auth token for the registry # ${...} is a placeholder for environment variables //http://localhost:4873/:_authToken=${NPM_TOKEN} # or you could set a username and password # note that the password is base64 encoded //http://localhost:4873/:username=myusername //http://localhost:4873/:_password=${NPM_PASSWORD} # or use _auth, which is your username and password # combined into a single string, which is then base 64 encoded //http://localhost:4873/:_auth=${NPM_AUTH} The following options are supported: * `_authToken` * `username` * `_password` (base64 encoded password) * `_auth` (base64 encoded username:password, e.g. `btoa(username + ":" + password)`) The equivalent `bunfig.toml` option is to add a key in `install.scopes`: [install.scopes] myorg = { url = "http://localhost:4873/", username = "myusername", password = "$NPM_PASSWORD" }