### `bun install` bun install is a fast package manager & npm client. bun install can be configured via `bunfig.toml`, environment variables, and CLI flags. #### Configuring `bun install` with `bunfig.toml` `bunfig.toml` is searched for in the following paths on `bun install`, `bun remove`, and `bun add`: 1. `$XDG_CONFIG_HOME/.bunfig.toml` or `$HOME/.bunfig.toml` 2. `./bunfig.toml` If both are found, the results are merged together. Configuring with `bunfig.toml` is optional. Bun tries to be zero configuration in general, but that's not always possible. ```toml # Using scoped packages with bun install [install.scopes] # Scope name The value can be a URL string or an object "@mybigcompany" = { token = "123456", url = "https://registry.mybigcompany.com" } # URL is optional and fallsback to the default registry # The "@" in the scope is optional mybigcompany2 = { token = "123456" } # Environment variables can be referenced as a string that starts with $ and it will be replaced mybigcompany3 = { token = "$npm_config_token" } # Setting username and password turns it into a Basic Auth header by taking base64("username:password") mybigcompany4 = { username = "myusername", password = "$npm_config_password", url = "https://registry.yarnpkg.com/" } # You can set username and password in the registry URL. This is the same as above. mybigcompany5 = "https://username:password@registry.yarnpkg.com/" # You can set a token for a registry URL: mybigcompany6 = "https://:$NPM_CONFIG_TOKEN@registry.yarnpkg.com/" [install] # Default registry # can be a URL string or an object registry = "https://registry.yarnpkg.com/" # as an object #registry = { url = "https://registry.yarnpkg.com/", token = "123456" } # Install for production? This is the equivalent to the "--production" CLI argument production = false # Disallow changes to lockfile? This is the equivalent to the "--fozen-lockfile" CLI argument frozenLockfile = false # Don't actually install dryRun = true # Install optionalDependencies (default: true) optional = true # Install local devDependencies (default: true) dev = true # Install peerDependencies (default: false) peer = false # When using `bun install -g`, install packages here globalDir = "~/.bun/install/global" # When using `bun install -g`, link package bins here globalBinDir = "~/.bun/bin" # cache-related configuration [install.cache] # The directory to use for the cache dir = "~/.bun/install/cache" # Don't load from the global cache. # Note: Bun may still write to node_modules/.cache disable = false # Always resolve the latest versions from the registry disableManifest = false # Lockfile-related configuration [install.lockfile] # Print a yarn v1 lockfile # Note: it does not load the lockfile, it just converts bun.lockb into a yarn.lock print = "yarn" # Path to read bun.lockb from path = "bun.lockb" # Path to save bun.lockb to savePath = "bun.lockb" # Save the lockfile to disk save = true ``` If it's easier to read as TypeScript types: ```ts export interface Root { install: Install; } export interface Install { scopes: Scopes; registry: Registry; production: boolean; frozenLockfile: boolean; dryRun: boolean; optional: boolean; dev: boolean; peer: boolean; globalDir: string; globalBinDir: string; cache: Cache; lockfile: Lockfile; logLevel: "debug" | "error" | "warn"; } type Registry = | string | { url?: string; token?: string; username?: string; password?: string; }; type Scopes = Record; export interface Cache { dir: string; disable: boolean; disableManifest: boolean; } export interface Lockfile { print?: "yarn"; path: string; savePath: string; save: boolean; } ``` ## Configuring with environment variables Environment variables have a higher priority than `bunfig.toml`. | Name | Description | | -------------------------------- | ------------------------------------------------------------- | | BUN_CONFIG_REGISTRY | Set an npm registry (default: ) | | BUN_CONFIG_TOKEN | Set an auth token (currently does nothing) | | BUN_CONFIG_LOCKFILE_SAVE_PATH | File path to save the lockfile to (default: bun.lockb) | | BUN_CONFIG_YARN_LOCKFILE | Save a Yarn v1-style yarn.lock | | BUN_CONFIG_LINK_NATIVE_BINS | Point `bin` in package.json to a platform-specific dependency | | BUN_CONFIG_SKIP_SAVE_LOCKFILE | Don’t save a lockfile | | BUN_CONFIG_SKIP_LOAD_LOCKFILE | Don’t load a lockfile | | BUN_CONFIG_SKIP_INSTALL_PACKAGES | Don’t install any packages | Bun always tries to use the fastest available installation method for the target platform. On macOS, that’s `clonefile` and on Linux, that’s `hardlink`. You can change which installation method is used with the `--backend` flag. When unavailable or on error, `clonefile` and `hardlink` fallsback to a platform-specific implementation of copying files. Bun stores installed packages from npm in `~/.bun/install/cache/${name}@${version}`. Note that if the semver version has a `build` or a `pre` tag, it is replaced with a hash of that value instead. This is to reduce the chances of errors from long file paths, but unfortunately complicates figuring out where a package was installed on disk. When the `node_modules` folder exists, before installing, Bun checks if the `"name"` and `"version"` in `package/package.json` in the expected node_modules folder matches the expected `name` and `version`. This is how it determines whether it should install. It uses a custom JSON parser which stops parsing as soon as it finds `"name"` and `"version"`. When a `bun.lockb` doesn’t exist or `package.json` has changed dependencies, tarballs are downloaded & extracted eagerly while resolving. When a `bun.lockb` exists and `package.json` hasn’t changed, Bun downloads missing dependencies lazily. If the package with a matching `name` & `version` already exists in the expected location within `node_modules`, Bun won’t attempt to download the tarball. ## 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. ## Peer dependencies? Peer dependencies are handled similarly to yarn. `bun install` does not automatically install peer dependencies and will try to choose an existing dependency. ## Lockfile `bun.lockb` is Bun’s binary lockfile format. ## 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? For now, the easiest thing is to run `bun install -y`. That prints a Yarn v1-style yarn.lock file. ## 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](https://github.com/oven-sh/bun/blob/be03fc273a487ac402f19ad897778d74b6d72963/src/install/install.zig#L1825) 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. ## Cache To delete the cache: ```bash $ rm -rf ~/.bun/install/cache ``` ## Platform-specific backends `bun install` uses different system calls to install dependencies depending on the platform. This is a performance optimization. You can force a specific backend with the `--backend` flag. **`hardlink`** is the default backend on Linux. Benchmarking showed it to be the fastest on Linux. ```bash $ rm -rf node_modules $ bun install --backend hardlink ``` **`clonefile`** is the default backend on macOS. Benchmarking showed it to be the fastest on macOS. It is only available on macOS. ```bash $ rm -rf node_modules $ bun install --backend clonefile ``` **`clonefile_each_dir`** is similar to `clonefile`, except it clones each file individually per directory. It is only available on macOS and tends to perform slower than `clonefile`. Unlike `clonefile`, this does not recursively clone subdirectories in one system call. ```bash $ rm -rf node_modules $ bun install --backend clonefile_each_dir ``` **`copyfile`** is the fallback used when any of the above fail, and is the slowest. on macOS, it uses `fcopyfile()` and on linux it uses `copy_file_range()`. ```bash $ rm -rf node_modules $ bun install --backend copyfile ``` **`symlink`** is typically only used for `file:` dependencies (and eventually `link:`) internally. To prevent infinite loops, it skips symlinking the `node_modules` folder. If you install with `--backend=symlink`, Node.js won't resolve node_modules of dependencies unless each dependency has its own node_modules folder or you pass `--preserve-symlinks` to `node`. See [Node.js documentation on `--preserve-symlinks`](https://nodejs.org/api/cli.html#--preserve-symlinks). ```bash $ rm -rf node_modules $ bun install --backend symlink $ node --preserve-symlinks ./my-file.js # https://nodejs.org/api/cli.html#--preserve-symlinks ``` Bun's runtime does not currently expose an equivalent of `--preserve-symlinks`, though the code for it does exist. ## npm registry metadata bun uses a binary format for caching NPM registry responses. This loads much faster than JSON and tends to be smaller on disk. You will see these files in `~/.bun/install/cache/*.npm`. The filename pattern is `${hash(packageName)}.npm`. It’s a hash so that extra directories don’t need to be created for scoped packages. Bun's usage of `Cache-Control` ignores `Age`. This improves performance, but means bun may be about 5 minutes out of date to receive the latest package version metadata from npm. jarred/some-fixes-for-eventsource Unnamed repository; edit this file 'description' to name the repository.
aboutsummaryrefslogtreecommitdiff
AgeCommit message (Expand)AuthorFilesLines
2022-02-27[JS Parser] AST changes for class static block & private identifiersGravatar Jarred Sumner 1-5/+27
2022-02-27[JS Parser] Fix bug with unicode identifiersGravatar Jarred Sumner 2-31/+142
2022-02-27[JS Parser] #privateIdentifiersGravatar Jarred Sumner 1-105/+279
2022-02-27[JS Parser] Class Static Initialization BlocksGravatar Jarred Sumner 1-0/+62
2022-02-27[TS Parser] Support `export {type Foo}`Gravatar Jarred Sumner 6-26/+114
2022-02-25be more carefulGravatar Jarred Sumner 3-6/+11
2022-02-25Update cli.zigbun-v0.0.71Gravatar Jarred Sumner 1-2/+2
2022-02-25bump target nextjs versionGravatar Jarred Sumner 1-1/+1
2022-02-25[bun pm] add help menuGravatar Jarred Sumner 1-4/+22
2022-02-25Fix alignment bug with `bun --help`Gravatar Jarred Sumner 1-1/+1
2022-02-25hopefully no more unnecessary git statusGravatar Jarred Sumner 6-1/+1
2022-02-25Update bun-install-lockfile-status.shGravatar Jarred Sumner 1-9/+2
2022-02-25[bun install] Add metadata hashGravatar Jarred Sumner 9-19/+277
2022-02-25Update README.md (#119)Gravatar Evan Boehs 1-1/+0
2022-02-24[bun install] Skip saving the lockfile if there are no changesGravatar Jarred Sumner 3-12/+97
2022-02-24Update MakefileGravatar Jarred Sumner 1-1/+1
2022-02-24Update MakefileGravatar Jarred Sumner 1-1/+0
2022-02-24Update WebKitGravatar Jarred Sumner 1-0/+0
2022-02-24Update generated versionsGravatar Jarred Sumner 1-2/+2
2022-02-24Update MakefileGravatar Jarred Sumner 1-1/+3
2022-02-24miscGravatar Jarred Sumner 2-4/+4
2022-02-24[bun dev] Don't log errors twiceGravatar Jarred Sumner 1-1/+0
2022-02-24Add a simple HMR testGravatar Jarred Sumner 1-2/+40
2022-02-24Make alignment more consitentGravatar Jarred Sumner 3-4/+56
2022-02-24[bun dev] Fix bug with not transpiling files at the rootGravatar Jarred Sumner 2-21/+47
2022-02-24slightly clean up react exampleGravatar Jarred Sumner 5-55/+2
2022-02-24[bun-framework-next] Support Next.js 12.1Gravatar Jarred Sumner 6-25/+46
2022-02-24[bun.js] Implement `process.exit` (no callbacks yet)Gravatar Jarred Sumner 2-0/+29
2022-02-24[bun install] Print correct bin nameGravatar Jarred Sumner 1-1/+1
2022-02-24[bun install] Add integration test for bin linksGravatar Jarred Sumner 1-1/+7
2022-02-24Add WASM modules but disable it for nowGravatar Jarred Sumner 28-134/+530
2022-02-24bump build idGravatar Jarred Sumner 1-1/+1
2022-02-24fix test failure in path.resolveGravatar Jarred Sumner 1-2/+6
2022-02-24Ensure we run the process testGravatar Jarred Sumner 2-48/+54
2022-02-24Update javascript.zigGravatar Jarred Sumner 1-1/+110
2022-02-24[bun.js] Add `ShadowRealm`Gravatar Jarred Sumner 7-18/+70
2022-02-24[bun-framework-next] Remove TextEncoder & TextDecoder polyfillsGravatar Jarred Sumner 3-340/+19
2022-02-24Use a JSFinalobject for PathGravatar Jarred Sumner 2-81/+42
2022-02-24Expose TextEncoder & TextDecoder globallyGravatar Jarred Sumner 3-20/+750
2022-02-24[Web Platform] Implement TextEncoder & TextDecoderGravatar Jarred Sumner 12-358/+1044
2022-02-24move GCDeferralContextGravatar Jarred Sumner 2-18/+24
2022-02-24[JS Parser] ensure assertions are never run at runtimeGravatar Jarred Sumner 1-13/+18
2022-02-24misc cleanupGravatar Jarred Sumner 2-7/+18
2022-02-22Make format consistent with WebKitGravatar Jarred Sumner 20-3596/+4110
2022-02-22import assertion testGravatar Jarred Sumner 1-0/+33
2022-02-22snaspshotsGravatar Jarred Sumner 42-94/+113