bun-types 1.2.23 β†’ 1.2.24-canary.20251001T140657

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/docs/api/fetch.md CHANGED
@@ -233,6 +233,7 @@ In addition to the standard fetch options, Bun provides several extensions:
233
233
  ```ts
234
234
  const response = await fetch("http://example.com", {
235
235
  // Control automatic response decompression (default: true)
236
+ // Supports gzip, deflate, brotli (br), and zstd
236
237
  decompress: true,
237
238
 
238
239
  // Disable connection reuse for this request
@@ -336,10 +337,10 @@ This will print the request and response headers to your terminal:
336
337
  ```sh
337
338
  [fetch] > HTTP/1.1 GET http://example.com/
338
339
  [fetch] > Connection: keep-alive
339
- [fetch] > User-Agent: Bun/1.2.23
340
+ [fetch] > User-Agent: Bun/1.2.24-canary.20251001T140657
340
341
  [fetch] > Accept: */*
341
342
  [fetch] > Host: example.com
342
- [fetch] > Accept-Encoding: gzip, deflate, br
343
+ [fetch] > Accept-Encoding: gzip, deflate, br, zstd
343
344
 
344
345
  [fetch] < 200 OK
345
346
  [fetch] < Content-Encoding: gzip
package/docs/api/glob.md CHANGED
@@ -155,3 +155,24 @@ const glob = new Glob("\\!index.ts");
155
155
  glob.match("!index.ts"); // => true
156
156
  glob.match("index.ts"); // => false
157
157
  ```
158
+
159
+ ## Node.js `fs.glob()` compatibility
160
+
161
+ Bun also implements Node.js's `fs.glob()` functions with additional features:
162
+
163
+ ```ts
164
+ import { glob, globSync, promises } from "node:fs";
165
+
166
+ // Array of patterns
167
+ const files = await promises.glob(["**/*.ts", "**/*.js"]);
168
+
169
+ // Exclude patterns
170
+ const filtered = await promises.glob("**/*", {
171
+ exclude: ["node_modules/**", "*.test.*"],
172
+ });
173
+ ```
174
+
175
+ All three functions (`fs.glob()`, `fs.globSync()`, `fs.promises.glob()`) support:
176
+
177
+ - Array of patterns as the first argument
178
+ - `exclude` option to filter results
package/docs/api/redis.md CHANGED
@@ -88,6 +88,9 @@ await redis.set("user:1:name", "Alice");
88
88
  // Get a key
89
89
  const name = await redis.get("user:1:name");
90
90
 
91
+ // Get a key as Uint8Array
92
+ const buffer = await redis.getBuffer("user:1:name");
93
+
91
94
  // Delete a key
92
95
  await redis.del("user:1:name");
93
96
 
@@ -132,6 +135,10 @@ await redis.hmset("user:123", [
132
135
  const userFields = await redis.hmget("user:123", ["name", "email"]);
133
136
  console.log(userFields); // ["Alice", "alice@example.com"]
134
137
 
138
+ // Get single field from hash (returns value directly, null if missing)
139
+ const userName = await redis.hget("user:123", "name");
140
+ console.log(userName); // "Alice"
141
+
135
142
  // Increment a numeric field in a hash
136
143
  await redis.hincrby("user:123", "visits", 1);
137
144
 
package/docs/api/spawn.md CHANGED
@@ -140,7 +140,7 @@ You can read results from the subprocess via the `stdout` and `stderr` propertie
140
140
  ```ts
141
141
  const proc = Bun.spawn(["bun", "--version"]);
142
142
  const text = await proc.stdout.text();
143
- console.log(text); // => "1.2.23\n"
143
+ console.log(text); // => "1.2.24-canary.20251001T140657\n"
144
144
  ```
145
145
 
146
146
  Configure the output stream by passing one of the following values to `stdout/stderr`:
package/docs/api/sql.md CHANGED
@@ -377,6 +377,22 @@ const users = [
377
377
  await sql`SELECT * FROM users WHERE id IN ${sql(users, "id")}`;
378
378
  ```
379
379
 
380
+ ### `sql.array` helper
381
+
382
+ The `sql.array` helper creates PostgreSQL array literals from JavaScript arrays:
383
+
384
+ ```ts
385
+ // Create array literals for PostgreSQL
386
+ await sql`INSERT INTO tags (items) VALUES (${sql.array(["red", "blue", "green"])})`;
387
+ // Generates: INSERT INTO tags (items) VALUES (ARRAY['red', 'blue', 'green'])
388
+
389
+ // Works with numeric arrays too
390
+ await sql`SELECT * FROM products WHERE ids = ANY(${sql.array([1, 2, 3])})`;
391
+ // Generates: SELECT * FROM products WHERE ids = ANY(ARRAY[1, 2, 3])
392
+ ```
393
+
394
+ **Note**: `sql.array` is PostgreSQL-only. Multi-dimensional arrays and NULL elements may not be supported yet.
395
+
380
396
  ## `sql``.simple()`
381
397
 
382
398
  The PostgreSQL wire protocol supports two types of queries: "simple" and "extended". Simple queries can contain multiple statements but don't support parameters, while extended queries (the default) support parameters but only allow one statement.
@@ -663,6 +663,8 @@ class Statement<Params, ReturnType> {
663
663
  toString(): string; // serialize to SQL
664
664
 
665
665
  columnNames: string[]; // the column names of the result set
666
+ columnTypes: string[]; // types based on actual values in first row (call .get()/.all() first)
667
+ declaredTypes: (string | null)[]; // types from CREATE TABLE schema (call .get()/.all() first)
666
668
  paramsCount: number; // the number of parameters expected by the statement
667
669
  native: any; // the native object representing the statement
668
670
 
@@ -28,6 +28,20 @@ for await (const chunk of stream) {
28
28
  }
29
29
  ```
30
30
 
31
+ `ReadableStream` also provides convenience methods for consuming the entire stream:
32
+
33
+ ```ts
34
+ const stream = new ReadableStream({
35
+ start(controller) {
36
+ controller.enqueue("hello world");
37
+ controller.close();
38
+ },
39
+ });
40
+
41
+ const data = await stream.text(); // => "hello world"
42
+ // Also available: .json(), .bytes(), .blob()
43
+ ```
44
+
31
45
  ## Direct `ReadableStream`
32
46
 
33
47
  Bun implements an optimized version of `ReadableStream` that avoid unnecessary data copying & queue management logic. With a traditional `ReadableStream`, chunks of data are _enqueued_. Each chunk is copied into a queue, where it sits until the stream is ready to send more data.
package/docs/api/utils.md CHANGED
@@ -602,6 +602,40 @@ dec.decode(decompressed);
602
602
  // => "hellohellohello..."
603
603
  ```
604
604
 
605
+ ## `Bun.zstdCompress()` / `Bun.zstdCompressSync()`
606
+
607
+ Compresses a `Uint8Array` using the Zstandard algorithm.
608
+
609
+ ```ts
610
+ const buf = Buffer.from("hello".repeat(100));
611
+
612
+ // Synchronous
613
+ const compressedSync = Bun.zstdCompressSync(buf);
614
+ // Asynchronous
615
+ const compressedAsync = await Bun.zstdCompress(buf);
616
+
617
+ // With compression level (1-22, default: 3)
618
+ const compressedLevel = Bun.zstdCompressSync(buf, { level: 6 });
619
+ ```
620
+
621
+ ## `Bun.zstdDecompress()` / `Bun.zstdDecompressSync()`
622
+
623
+ Decompresses a `Uint8Array` using the Zstandard algorithm.
624
+
625
+ ```ts
626
+ const buf = Buffer.from("hello".repeat(100));
627
+ const compressed = Bun.zstdCompressSync(buf);
628
+
629
+ // Synchronous
630
+ const decompressedSync = Bun.zstdDecompressSync(compressed);
631
+ // Asynchronous
632
+ const decompressedAsync = await Bun.zstdDecompress(compressed);
633
+
634
+ const dec = new TextDecoder();
635
+ dec.decode(decompressedSync);
636
+ // => "hellohellohello..."
637
+ ```
638
+
605
639
  ## `Bun.inspect()`
606
640
 
607
641
  Serializes an object to a `string` exactly as it would be printed by `console.log`.
@@ -279,6 +279,9 @@ Bun implements the `WebSocket` class. To create a WebSocket client that connects
279
279
 
280
280
  ```ts
281
281
  const socket = new WebSocket("ws://localhost:3000");
282
+
283
+ // With subprotocol negotiation
284
+ const socket2 = new WebSocket("ws://localhost:3000", ["soap", "wamp"]);
282
285
  ```
283
286
 
284
287
  In browsers, the cookies that are currently set on the page will be sent with the WebSocket upgrade request. This is a standard feature of the `WebSocket` API.
@@ -293,6 +296,17 @@ const socket = new WebSocket("ws://localhost:3000", {
293
296
  });
294
297
  ```
295
298
 
299
+ ### Client compression
300
+
301
+ WebSocket clients support permessage-deflate compression. The `extensions` property shows negotiated compression:
302
+
303
+ ```ts
304
+ const socket = new WebSocket("wss://echo.websocket.org");
305
+ socket.addEventListener("open", () => {
306
+ console.log(socket.extensions); // => "permessage-deflate"
307
+ });
308
+ ```
309
+
296
310
  To add event listeners to the socket:
297
311
 
298
312
  ```ts
@@ -282,6 +282,31 @@ const worker = new Worker("./i-am-smol.ts", {
282
282
  Setting `smol: true` sets `JSC::HeapSize` to be `Small` instead of the default `Large`.
283
283
  {% /details %}
284
284
 
285
+ ## Environment Data
286
+
287
+ Share data between the main thread and workers using `setEnvironmentData()` and `getEnvironmentData()`.
288
+
289
+ ```js
290
+ import { setEnvironmentData, getEnvironmentData } from "worker_threads";
291
+
292
+ // In main thread
293
+ setEnvironmentData("config", { apiUrl: "https://api.example.com" });
294
+
295
+ // In worker
296
+ const config = getEnvironmentData("config");
297
+ console.log(config); // => { apiUrl: "https://api.example.com" }
298
+ ```
299
+
300
+ ## Worker Events
301
+
302
+ Listen for worker creation events using `process.emit()`:
303
+
304
+ ```js
305
+ process.on("worker", worker => {
306
+ console.log("New worker created:", worker.threadId);
307
+ });
308
+ ```
309
+
285
310
  ## `Bun.isMainThread`
286
311
 
287
312
  You can check if you're in the main thread by checking `Bun.isMainThread`.
@@ -140,6 +140,19 @@ The `--sourcemap` argument embeds a sourcemap compressed with zstd, so that erro
140
140
 
141
141
  The `--bytecode` argument enables bytecode compilation. Every time you run JavaScript code in Bun, JavaScriptCore (the engine) will compile your source code into bytecode. We can move this parsing work from runtime to bundle time, saving you startup time.
142
142
 
143
+ ## Embedding runtime arguments
144
+
145
+ **`--compile-exec-argv="args"`** - Embed runtime arguments that are available via `process.execArgv`:
146
+
147
+ ```bash
148
+ bun build --compile --compile-exec-argv="--smol --user-agent=MyBot" ./app.ts --outfile myapp
149
+ ```
150
+
151
+ ```js
152
+ // In the compiled app
153
+ console.log(process.execArgv); // ["--smol", "--user-agent=MyBot"]
154
+ ```
155
+
143
156
  ## Act as the Bun CLI
144
157
 
145
158
  {% note %}
@@ -313,6 +313,14 @@ $ bun build --entrypoints ./index.ts --outdir ./out --target browser
313
313
 
314
314
  Depending on the target, Bun will apply different module resolution rules and optimizations.
315
315
 
316
+ ### Module resolution
317
+
318
+ Bun supports the `NODE_PATH` environment variable for additional module resolution paths:
319
+
320
+ ```bash
321
+ NODE_PATH=./src bun build ./entry.js --outdir ./dist
322
+ ```
323
+
316
324
  <!-- - Module resolution. For example, when bundling for the browser, Bun will prioritize the `"browser"` export condition when resolving imports. An error will be thrown if any Node.js or Bun built-ins are imported or used, e.g. `node:fs` or `Bun.serve`. -->
317
325
 
318
326
  {% table %}
@@ -392,6 +400,55 @@ $ bun build ./index.tsx --outdir ./out --format cjs
392
400
 
393
401
  TODO: document IIFE once we support globalNames.
394
402
 
403
+ ### `jsx`
404
+
405
+ Configure JSX transform behavior. Allows fine-grained control over how JSX is compiled.
406
+
407
+ **Classic runtime example** (uses `factory` and `fragment`):
408
+
409
+ {% codetabs %}
410
+
411
+ ```ts#JavaScript
412
+ await Bun.build({
413
+ entrypoints: ['./app.tsx'],
414
+ outdir: './out',
415
+ jsx: {
416
+ factory: 'h',
417
+ fragment: 'Fragment',
418
+ runtime: 'classic',
419
+ },
420
+ })
421
+ ```
422
+
423
+ ```bash#CLI
424
+ # JSX configuration is handled via bunfig.toml or tsconfig.json
425
+ $ bun build ./app.tsx --outdir ./out
426
+ ```
427
+
428
+ {% /codetabs %}
429
+
430
+ **Automatic runtime example** (uses `importSource`):
431
+
432
+ {% codetabs %}
433
+
434
+ ```ts#JavaScript
435
+ await Bun.build({
436
+ entrypoints: ['./app.tsx'],
437
+ outdir: './out',
438
+ jsx: {
439
+ importSource: 'preact',
440
+ runtime: 'automatic',
441
+ },
442
+ })
443
+ ```
444
+
445
+ ```bash#CLI
446
+ # JSX configuration is handled via bunfig.toml or tsconfig.json
447
+ $ bun build ./app.tsx --outdir ./out
448
+ ```
449
+
450
+ {% /codetabs %}
451
+
395
452
  ### `splitting`
396
453
 
397
454
  Whether to enable code splitting.
@@ -1519,6 +1576,15 @@ interface BuildConfig {
1519
1576
  * @default "esm"
1520
1577
  */
1521
1578
  format?: "esm" | "cjs" | "iife";
1579
+ /**
1580
+ * JSX configuration object for controlling JSX transform behavior
1581
+ */
1582
+ jsx?: {
1583
+ factory?: string;
1584
+ fragment?: string;
1585
+ importSource?: string;
1586
+ runtime?: "automatic" | "classic";
1587
+ };
1522
1588
  naming?:
1523
1589
  | string
1524
1590
  | {
@@ -176,7 +176,21 @@ When a `bun.lock` exists and `package.json` hasn’t changed, Bun downloads miss
176
176
 
177
177
  ## Platform-specific dependencies?
178
178
 
179
- 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.
179
+ 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.
180
+
181
+ ### `--cpu` and `--os` flags
182
+
183
+ You can override the target platform for package selection:
184
+
185
+ ```bash
186
+ bun install --cpu=x64 --os=linux
187
+ ```
188
+
189
+ This installs packages for the specified platform instead of the current system. Useful for cross-platform builds or when preparing deployments for different environments.
190
+
191
+ **Accepted values for `--cpu`**: `arm64`, `x64`, `ia32`, `ppc64`, `s390x`
192
+
193
+ **Accepted values for `--os`**: `linux`, `darwin`, `win32`, `freebsd`, `openbsd`, `sunos`, `aix`
180
194
 
181
195
  ## Peer dependencies?
182
196
 
@@ -245,3 +259,91 @@ bun uses a binary format for caching NPM registry responses. This loads much fas
245
259
  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.
246
260
 
247
261
  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.
262
+
263
+ ## pnpm migration
264
+
265
+ Bun automatically migrates projects from pnpm to bun. When a `pnpm-lock.yaml` file is detected and no `bun.lock` file exists, Bun will automatically migrate the lockfile to `bun.lock` during installation. The original `pnpm-lock.yaml` file remains unmodified.
266
+
267
+ ```bash
268
+ bun install
269
+ ```
270
+
271
+ **Note**: Migration only runs when `bun.lock` is absent. There is currently no opt-out flag for pnpm migration.
272
+
273
+ The migration process handles:
274
+
275
+ ### Lockfile Migration
276
+
277
+ - Converts `pnpm-lock.yaml` to `bun.lock` format
278
+ - Preserves package versions and resolution information
279
+ - Maintains dependency relationships and peer dependencies
280
+ - Handles patched dependencies with integrity hashes
281
+
282
+ ### Workspace Configuration
283
+
284
+ When a `pnpm-workspace.yaml` file exists, Bun migrates workspace settings to your root `package.json`:
285
+
286
+ ```yaml
287
+ # pnpm-workspace.yaml
288
+ packages:
289
+ - "apps/*"
290
+ - "packages/*"
291
+
292
+ catalog:
293
+ react: ^18.0.0
294
+ typescript: ^5.0.0
295
+
296
+ catalogs:
297
+ build:
298
+ webpack: ^5.0.0
299
+ babel: ^7.0.0
300
+ ```
301
+
302
+ The workspace packages list and catalogs are moved to the `workspaces` field in `package.json`:
303
+
304
+ ```json
305
+ {
306
+ "workspaces": {
307
+ "packages": ["apps/*", "packages/*"],
308
+ "catalog": {
309
+ "react": "^18.0.0",
310
+ "typescript": "^5.0.0"
311
+ },
312
+ "catalogs": {
313
+ "build": {
314
+ "webpack": "^5.0.0",
315
+ "babel": "^7.0.0"
316
+ }
317
+ }
318
+ }
319
+ }
320
+ ```
321
+
322
+ ### Catalog Dependencies
323
+
324
+ Dependencies using pnpm's `catalog:` protocol are preserved:
325
+
326
+ ```json
327
+ {
328
+ "dependencies": {
329
+ "react": "catalog:",
330
+ "webpack": "catalog:build"
331
+ }
332
+ }
333
+ ```
334
+
335
+ ### Configuration Migration
336
+
337
+ The following pnpm configuration is migrated from both `pnpm-lock.yaml` and `pnpm-workspace.yaml`:
338
+
339
+ - **Overrides**: Moved from `pnpm.overrides` to root-level `overrides` in `package.json`
340
+ - **Patched Dependencies**: Moved from `pnpm.patchedDependencies` to root-level `patchedDependencies` in `package.json`
341
+ - **Workspace Overrides**: Applied from `pnpm-workspace.yaml` to root `package.json`
342
+
343
+ ### Requirements
344
+
345
+ - Requires pnpm lockfile version 7 or higher
346
+ - Workspace packages must have a `name` field in their `package.json`
347
+ - All catalog entries referenced by dependencies must exist in the catalogs definition
348
+
349
+ After migration, you can safely remove `pnpm-lock.yaml` and `pnpm-workspace.yaml` files.
package/docs/cli/bunx.md CHANGED
@@ -63,6 +63,15 @@ $ bunx --bun my-cli # good
63
63
  $ bunx my-cli --bun # bad
64
64
  ```
65
65
 
66
+ ## Package flag
67
+
68
+ **`--package <pkg>` or `-p <pkg>`** - Run binary from specific package. Useful when binary name differs from package name:
69
+
70
+ ```bash
71
+ bunx -p renovate renovate-config-validator
72
+ bunx --package @angular/cli ng
73
+ ```
74
+
66
75
  To force bun to always be used with a script, use a shebang.
67
76
 
68
77
  ```
package/docs/cli/init.md CHANGED
@@ -33,6 +33,11 @@ It creates:
33
33
  - an entry point which defaults to `index.ts` unless any of `index.{tsx, jsx, js, mts, mjs}` exist or the `package.json` specifies a `module` or `main` field
34
34
  - a `README.md` file
35
35
 
36
+ AI Agent rules (disable with `$BUN_AGENT_RULE_DISABLED=1`):
37
+
38
+ - a `CLAUDE.md` file when Claude CLI is detected (disable with `CLAUDE_CODE_AGENT_RULE_DISABLED` env var)
39
+ - a `.cursor/rules/*.mdc` file to guide [Cursor AI](https://cursor.sh) to use Bun instead of Node.js and npm when Cursor is detected
40
+
36
41
  If you pass `-y` or `--yes`, it will assume you want to continue without asking questions.
37
42
 
38
43
  At the end, it runs `bun install` to install `@types/bun`.
@@ -44,4 +44,47 @@ You can also pass glob patterns to filter by workspace names:
44
44
 
45
45
  {% bunOutdatedTerminal glob="{e,t}*" displayGlob="--filter='@monorepo/{types,cli}'" /%}
46
46
 
47
+ ### Catalog Dependencies
48
+
49
+ `bun outdated` supports checking catalog dependencies defined in `package.json`:
50
+
51
+ ```sh
52
+ $ bun outdated -r
53
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
54
+ β”‚ Package β”‚ Current β”‚ Update β”‚ Latest β”‚ Workspace β”‚
55
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
56
+ β”‚ body-parser β”‚ 1.19.0 β”‚ 1.19.0 β”‚ 2.2.0 β”‚ @test/shared β”‚
57
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
58
+ β”‚ cors β”‚ 2.8.0 β”‚ 2.8.0 β”‚ 2.8.5 β”‚ @test/shared β”‚
59
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
60
+ β”‚ chalk β”‚ 4.0.0 β”‚ 4.0.0 β”‚ 5.6.2 β”‚ @test/utils β”‚
61
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
62
+ β”‚ uuid β”‚ 8.0.0 β”‚ 8.0.0 β”‚ 13.0.0 β”‚ @test/utils β”‚
63
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
64
+ β”‚ axios β”‚ 0.21.0 β”‚ 0.21.0 β”‚ 1.12.2 β”‚ catalog (@test/app) β”‚
65
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
66
+ β”‚ lodash β”‚ 4.17.15 β”‚ 4.17.15 β”‚ 4.17.21 β”‚ catalog (@test/app, @test/app) β”‚
67
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
68
+ β”‚ react β”‚ 17.0.0 β”‚ 17.0.0 β”‚ 19.1.1 β”‚ catalog (@test/app) β”‚
69
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
70
+ β”‚ react-dom β”‚ 17.0.0 β”‚ 17.0.0 β”‚ 19.1.1 β”‚ catalog (@test/app) β”‚
71
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
72
+ β”‚ express β”‚ 4.17.0 β”‚ 4.17.0 β”‚ 5.1.0 β”‚ catalog (@test/shared) β”‚
73
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
74
+ β”‚ moment β”‚ 2.24.0 β”‚ 2.24.0 β”‚ 2.30.1 β”‚ catalog (@test/utils) β”‚
75
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
76
+ β”‚ @types/node (dev) β”‚ 14.0.0 β”‚ 14.0.0 β”‚ 24.5.2 β”‚ @test/shared β”‚
77
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
78
+ β”‚ @types/react (dev) β”‚ 17.0.0 β”‚ 17.0.0 β”‚ 19.1.15 β”‚ catalog:testing (@test/app) β”‚
79
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
80
+ β”‚ eslint (dev) β”‚ 7.0.0 β”‚ 7.0.0 β”‚ 9.36.0 β”‚ catalog:testing (@test/app) β”‚
81
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
82
+ β”‚ typescript (dev) β”‚ 4.9.5 β”‚ 4.9.5 β”‚ 5.9.2 β”‚ catalog:build (@test/app) β”‚
83
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
84
+ β”‚ jest (dev) β”‚ 26.0.0 β”‚ 26.0.0 β”‚ 30.2.0 β”‚ catalog:testing (@test/shared) β”‚
85
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
86
+ β”‚ prettier (dev) β”‚ 2.0.0 β”‚ 2.0.0 β”‚ 3.6.2 β”‚ catalog:build (@test/utils) β”‚
87
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
88
+ ```
89
+
47
90
  {% bunCLIUsage command="outdated" /%}
package/docs/cli/pm.md CHANGED
@@ -213,7 +213,7 @@ To display current package version and help:
213
213
 
214
214
  ```bash
215
215
  $ bun pm version
216
- bun pm version v1.2.23 (ca7428e9)
216
+ bun pm version v1.2.24-canary.20251001T140657 (ca7428e9)
217
217
  Current package version: v1.0.0
218
218
 
219
219
  Increment:
@@ -7,7 +7,7 @@ Use `bun publish` to publish a package to the npm registry.
7
7
  $ bun publish
8
8
 
9
9
  ## Output
10
- bun publish v1.2.23 (ca7428e9)
10
+ bun publish v1.2.24-canary.20251001T140657 (ca7428e9)
11
11
 
12
12
  packed 203B package.json
13
13
  packed 224B README.md
@@ -82,6 +82,16 @@ The `--dry-run` flag can be used to simulate the publish process without actuall
82
82
  $ bun publish --dry-run
83
83
  ```
84
84
 
85
+ ### `--tolerate-republish`
86
+
87
+ The `--tolerate-republish` flag makes `bun publish` exit with code 0 instead of code 1 when attempting to republish over an existing version number. This is useful in automated workflows where republishing the same version might occur and should not be treated as an error.
88
+
89
+ ```sh
90
+ $ bun publish --tolerate-republish
91
+ ```
92
+
93
+ Without this flag, attempting to publish a version that already exists will result in an error and exit code 1. With this flag, the command will exit successfully even when trying to republish an existing version.
94
+
85
95
  ### `--gzip-level`
86
96
 
87
97
  Specify the level of gzip compression to use when packing the package. Only applies to `bun publish` without a tarball path argument. Values range from `0` to `9` (default is `9`).
package/docs/cli/run.md CHANGED
@@ -151,6 +151,14 @@ By default, Bun respects this shebang and executes the script with `node`. Howev
151
151
  $ bun run --bun vite
152
152
  ```
153
153
 
154
+ ### `--no-addons`
155
+
156
+ Disable native addons and use the `node-addons` export condition.
157
+
158
+ ```bash
159
+ $ bun --no-addons run server.js
160
+ ```
161
+
154
162
  ### Filtering
155
163
 
156
164
  In monorepos containing multiple packages, you can use the `--filter` argument to execute scripts in many packages at once.
@@ -166,6 +174,14 @@ will execute `<script>` in both `bar` and `baz`, but not in `foo`.
166
174
 
167
175
  Find more details in the docs page for [filter](https://bun.com/docs/cli/filter#running-scripts-with-filter).
168
176
 
177
+ ### `--workspaces`
178
+
179
+ Run scripts across all workspaces in the monorepo:
180
+
181
+ ```bash
182
+ bun run --workspaces test
183
+ ```
184
+
169
185
  ## `bun run -` to pipe code from stdin
170
186
 
171
187
  `bun run -` lets you read JavaScript, TypeScript, TSX, or JSX from stdin and execute it without writing to a temporary file first.
@@ -212,6 +228,14 @@ $ bun --smol run index.tsx
212
228
 
213
229
  This causes the garbage collector to run more frequently, which can slow down execution. However, it can be useful in environments with limited memory. Bun automatically adjusts the garbage collector's heap size based on the available memory (accounting for cgroups and other memory limits) with and without the `--smol` flag, so this is mostly useful for cases where you want to make the heap size grow more slowly.
214
230
 
231
+ ## `--user-agent`
232
+
233
+ **`--user-agent <string>`** - Set User-Agent header for all `fetch()` requests:
234
+
235
+ ```bash
236
+ bun --user-agent "MyBot/1.0" run index.tsx
237
+ ```
238
+
215
239
  ## Resolution order
216
240
 
217
241
  Absolute paths and paths starting with `./` or `.\\` are always executed as source files. Unless using `bun run`, running a file with an allowed extension will prefer the file over a package.json script.
@@ -223,4 +247,15 @@ When there is a package.json script and a file with the same name, `bun run` pri
223
247
  3. Binaries from project packages, eg `bun add eslint && bun run eslint`
224
248
  4. (`bun run` only) System commands, eg `bun run ls`
225
249
 
250
+ ### `--unhandled-rejections`
251
+
252
+ Configure how unhandled promise rejections are handled:
253
+
254
+ ```bash
255
+ $ bun --unhandled-rejections=throw script.js # Throw exception (terminate immediately)
256
+ $ bun --unhandled-rejections=strict script.js # Throw exception (emit rejectionHandled if handled later)
257
+ $ bun --unhandled-rejections=warn script.js # Print warning to stderr (default in Node.js)
258
+ $ bun --unhandled-rejections=none script.js # Silently ignore
259
+ ```
260
+
226
261
  {% bunCLIUsage command="run" /%}
package/docs/cli/test.md CHANGED
@@ -47,6 +47,8 @@ To filter by _test name_, use the `-t`/`--test-name-pattern` flag.
47
47
  $ bun test --test-name-pattern addition
48
48
  ```
49
49
 
50
+ When no tests match the filter, `bun test` exits with code 1.
51
+
50
52
  To run a specific file in the test runner, make sure the path starts with `./` or `/` to distinguish it from a filter name.
51
53
 
52
54
  ```bash
@@ -186,6 +188,11 @@ test.serial("second serial test", () => {
186
188
  test("independent test", () => {
187
189
  expect(true).toBe(true);
188
190
  });
191
+
192
+ // Chaining test qualifiers
193
+ test.failing.each([1, 2, 3])("chained qualifiers %d", input => {
194
+ expect(input).toBe(0); // This test is expected to fail for each input
195
+ });
189
196
  ```
190
197
 
191
198
  ## Rerun tests