Bun

Bun v1.2.19


Jarred Sumner · 2025年7月19日

Bun 是構建和測試全棧 JavaScript 和 TypeScript 應用程式的完整工具集。如果您是 Bun 的新手,可以從 Bun 1.0 部落格文章中瞭解更多資訊。

安裝 Bun

curl
npm
powershell
scoop
brew
docker
curl
curl -fsSL https://bun.nodejs.com.tw/install | bash
npm
npm install -g bun
powershell
powershell -c "irm bun.sh/install.ps1|iex"
scoop
scoop install bun
brew
brew tap oven-sh/bun
brew install bun
docker
docker pull oven/bun
docker run --rm --init --ulimit memlock=-1:-1 oven/bun

升級 Bun

bun upgrade

bun install --linker=isolated

在 Windows 上,獨立安裝也能帶來顯著的效能改進。

bun update --interactive

bun pm pkg 幫助您管理 package.json

引入了一個新命令 bun pm pkg,用於以程式設計方式管理您的 package.json 檔案。此命令簡化了指令碼編寫和專案配置更改的自動化。

它支援四個子命令

  • get:檢索一個或多個值。
  • set:新增或更新鍵值對。
  • delete:刪除鍵。
  • fix:自動糾正常見錯誤。

您可以使用點表示法 (scripts.build) 訪問巢狀欄位,或使用方括號表示法訪問包含特殊字元的鍵 (scripts['test:watch'])。

# Get a single property
bun pm pkg get name

# Get multiple properties
bun pm pkg get name version

# Set a simple property
bun pm pkg set name="my-package"

# Set multiple properties, including a nested one
bun pm pkg set scripts.test="jest" version=2.0.0

# Delete a single property
bun pm pkg delete description

# Delete multiple nested properties
bun pm pkg delete scripts.test contributors[0]

感謝 @riskymh 的貢獻!

在 workspaces 中更快的 bun install

已修復一個導致在安裝過程中多次重新評估 workspace 包的 bug。這使得使用 Bun workspaces 的 monorepos 的安裝更快、更可靠。

感謝 @dylan-conway 的改進!

devDependencies > optionalDependencies > dependencies > peerDependencies

已修復依賴解析邏輯中的歧義,該歧義可能導致在同一包列在多個依賴組(如 dependenciesdevDependencies)中時安裝意外版本的包。依賴解析優先順序已調整為 devDependencies > optionalDependencies > dependencies > peerDependencies

在這種情況下我們應該做什麼?

package.json
{
  "dependencies": {
    "react": "18.2.0"
  },
  "devDependencies": {
    "react": "18.3.0"
  },
  "peerDependencies": {
    "react": "18.2.1"
  }
}

正確答案:其他包管理器所做的那樣,因為現狀最不可能破壞應用程式。

bun pm pack 添加了 --quiet 標誌

bun pm pack 命令現在支援 --quiet 標誌。使用此標誌時,它會抑制所有詳細輸出,只將生成的 tarball 的檔名列印到 stdout。這對於需要捕獲檔名的指令碼和自動化工作流特別有用。

# Default output is verbose
bun pm pack
bun pack v1.2.18

packed 131B package.json
packed 40B index.js

my-package-1.0.0.tgz

Total files: 2
Shasum: f2451d6eb1e818f500a791d9aace80b394258a90
Unpacked size: 171B
Packed size: 249B

# --quiet makes it easy to capture the filename in a script
TARBALL=$(bun pm pack --quiet)
echo "Created: $TARBALL"
# > Created: my-package-1.0.0.tgz

bun installbun add 現在會讀取並應用專案 .npmrc 檔案中的 link-workspace-packagessave-exact 設定。這允許更精細地控制依賴項管理,與其他包管理器保持一致。

例如,要始終儲存確切的版本而不是使用 ^ 字首,您可以設定 save-exact=true

# ./.npmrc
save-exact=true
# With the .npmrc file above...
bun add is-odd

# ...bun adds the exact version to package.json
# "dependencies": {
#   "is-odd": "3.0.1"
# }

bun why 解釋了為什麼安裝一個包

為了幫助您除錯 node_modules 目錄,Bun 現在包含了 bun why <package> 命令。它會追蹤導致某個包被安裝的依賴鏈,向您確切地展示它為什麼是您專案的一部分。

該命令支援使用 glob 模式一次查詢多個包——例如 bun why "@types/*"——並支援 --depth--top 等標誌來控制輸出的詳細程度。

// See the dependency path to a package
$ bun why react

react@18.2.0
  └─ my-app@1.0.0 (requires ^18.0.0)

// Use glob patterns to query multiple packages
$ bun why "@types/*"

@types/react@18.2.15
  └─ dev my-app@1.0.0 (requires ^18.0.0)

@types/react-dom@18.2.7
  └─ dev my-app@1.0.0 (requires ^18.0.0)

感謝 @riskymh 的貢獻!

頂層 catalogpackage.json 中的 catalogs

為了簡化配置,bun install 現在支援在根 package.json 的頂層定義依賴 目錄。以前,這些欄位必須巢狀在 workspaces 物件中,這可能不太直觀。現在,您可以將它們宣告在根級別,以獲得更簡潔的設定。

// package.json
{
  "name": "my-monorepo",
  "workspaces": ["packages/*"],

  // `catalog` and `catalogs` can now be defined at the top-level
  // instead of being nested inside the `workspaces` object.
  "catalog": {
    "react": "18.2.0"
  },
  "catalogs": {
    "testing": {
      "@testing-library/react": "16.0.0",
    }
  }
}

VS Code 測試資源管理器整合

官方 Bun VS Code 擴充套件現在集成了原生測試資源管理器 UI。bun test 現在可以與擴充套件通訊,報告測試發現、進度和結果。

感謝 @riskymh 的貢獻!

AI 代理的緊湊輸出

bun test 輸出在 Claude Code 等 AI 代理中執行時更加緊湊,節省了上下文視窗。

test.each 中的 $variable 替換

bun test 現在支援 test.each 標題中的變數替換。這允許您透過直接引用每個測試用例物件中的屬性(包括巢狀屬性)來建立更具描述性的測試名稱。這使得 bun:test 與 Jest 和 Vitest 使用的流行 API 一致,並且通常比使用 printf 風格的格式說明符更易讀。

import { test, expect } from "bun:test";

const testCases = [
  { user: { name: "Alice" }, a: 1, b: 2, expected: 3 },
  { user: { name: "Bob" }, a: 5, b: 5, expected: 10 },
];

// The test runner will generate titles like:
// ✓ Add 1 and 2 for Alice
// ✓ Add 5 and 5 for Bob
test.each(testCases)("Add $a and $b for $user.name", ({ a, b, expected }) => {
  expect(a + b).toBe(expected);
});

感謝 @riskymh 的貢獻!

使用 test.coveragePathIgnorePatterns 忽略測試覆蓋率報告中的檔案

您現在可以使用 bun.toml 中的新 test.coveragePathIgnorePatterns 選項將檔案排除在測試覆蓋率報告之外。這對於忽略測試檔案、夾具或其他您不想包含在覆蓋率指標中的非原始碼檔案很有用。

該選項接受單個 glob 模式或模式陣列。與這些模式匹配的路徑的檔案將被從生成的覆蓋率報告中省略。

# bun.toml

[test]
# You can use a single pattern as a string
# coveragePathIgnorePatterns = "**/__tests__/**"

# Or an array of glob patterns
coveragePathIgnorePatterns = [
  "**/__tests__/**",
  "**/test-fixtures.ts",
]

感謝 @dylan-conway 的貢獻

生成的快照檔案 (.snap) 中的標題註釋包含一個 goo.gl 連結,這是一個正在棄用的 URL 縮短服務。此連結已更新為 https://bun.nodejs.com.tw/docs/test/snapshots,指向 Bun 關於快照測試的官方文件。

test.test.ts.snap
- // Bun Snapshot v1, https://goo.gl/fbAQLP
+ // Bun Snapshot v1, https://bun.nodejs.com.tw/docs/test/snapshots

感謝 @xanth3 的貢獻

Bun.sql 現在速度提高了 5 倍

Bun 內建的 PostgreSQL 客戶端 Bun.sql 現在會自動進行查詢流水線處理,這可以顯著提高效能。流水線處理允許在不等待前一個查詢響應的情況下發送多個查詢,從而降低網路延遲的影響。當並行執行許多小型、獨立的查詢時(例如,API 伺服器處理多個併發請求),這尤其有效。

此更改預設啟用,無需任何程式碼更改。在基準測試中,在 Bun 中執行的 Bun.sqlpostgres 包快約 3.4 倍,在高併發工作負載下比 Node.js 中的 postgres 快約 6 倍。

import { SQL } from "bun:sql";

const db = new SQL("postgres://user:pass@host:port/db");

// Bun automatically pipelines these queries,
// sending them to the server without waiting for each response individually.
const queries = [];
for (let i = 0; i < 100; i++) {
  // .execute() is used for fire-and-forget queries
  queries.push(db`SELECT ${i}`.execute());
}

// Await all results
const results = await Promise.all(queries);
console.log(results.length); // 100

await db.end();

感謝 @cirospaciari 的貢獻

使用 --sql-preconnect 減少首次查詢延遲

引入了一個新的 --sql-preconnect CLI 標誌,用於在使用 PostgreSQL 資料庫時減少首次查詢延遲。使用此標誌時,Bun 會在應用程式程式碼執行之前,在啟動時建立資料庫連線。這會“預熱”連線,使其立即可用於第一個查詢。

Bun 使用 DATABASE_URL 環境變數來確定連線詳細資訊。如果預連線嘗試失敗,您的應用程式不會崩潰;錯誤將得到優雅處理,並在首次查詢時再次嘗試連線。

# To use, set your DATABASE_URL and run Bun with the flag.
export DATABASE_URL="postgres://user:pass@host:port/db"

# Bun will connect to PostgreSQL before index.js is executed.
bun --sql-preconnect index.js

Windows 上的程式碼簽名獨立可執行檔案

使用 bun build --compile 在 Windows 上建立的獨立可執行檔案現在支援 Authenticode 程式碼簽名。

以前,Bun 會將自定義存檔格式附加到可執行檔案末尾。這種技術與 Windows 驗證程式碼簽名的方式不相容,因為它會在檔案簽名後修改檔案。

為了解決這個問題,Bun 現在將捆綁的原始碼和資產嵌入到 PE(可移植可執行)檔案中的專用 .bun 部分。這種方法可以保留可執行檔案結構的完整性,允許使用 signtool.exe 等工具對其進行簽名,而不會使簽名失效。

這種方法與我們支援 macOS 可執行檔案程式碼簽名的方式類似。

# Build a standalone executable on Windows
bun build ./my-script.ts --compile --outfile my-app.exe

# After building, the executable can be signed
signtool.exe sign /f MyCert.pfx /p MyPassword /t http://timestamp.digicert.com my-app.exe

啟動速度加快 1 毫秒,記憶體使用量減少 3MB。

Bun 現在啟動速度大約快 1 毫秒,記憶體使用量大約減少 3MB。

此改進來自我們 Zig 程式碼庫中的一項底層最佳化。Zig 中某些大型結構體賦值目前會導致不必要的 memcpy 操作,從而導致額外的頁面被分頁到程序的地址空間。

--console-depth=N 配置 console.log 深度

您現在可以配置使用 console.log 記錄的物件檢查深度,這對於除錯深度巢狀的資料結構很有用。預設深度仍為 2(與 Node.js 匹配)。

這可以透過 --console-depth CLI 標誌進行每次執行配置,或者在 bunfig.toml 中透過 console.depth 設定進行持久配置。CLI 標誌的優先順序高於 bunfig.toml 配置。

// index.js
const nested = {
  a: {
    b: {
      c: {
        d: "I am deeply nested",
      },
    },
  },
};
console.log(nested);

// By default, the output is truncated to a depth of 2.
// $ bun run index.js
// { a: { b: [Object] } }

// Run with `--console-depth=4` to see the full object.
// $ bun --console-depth=4 run index.js
// { a: { b: { c: { d: 'I am deeply nested' } } } }

// Alternatively, configure this in `bunfig.toml`:
// [run]
// console.depth = 4

bunfig.toml 中配置 console.log 深度

bunfig.toml
[run]
console.depth = 4

或者使用 --console-depth CLI 標誌

bun --console-depth=4 index.js

SIMD 加速的多行註釋解析

Bun 的 JavaScript 和 TypeScript 解析器現在使用 SIMD 指令來更快地掃描大型多行註釋。這可以顯著提高解析病態長多行註釋時的效能。

/*
  This is a very, very, very, very, very, very, very, very,
  very, very, very, very, very, very, very, very, very,
  very, very, very, very, very, very, very, very, very,
  very, very, very, very, very, very, very, very, very,
  very, very, very, very, very, very, very, very, very,
  very, very, very, very, very, very, very, very, very,
  very, very, very, very, very, very, very, very, very,
  ... and so on for many many many thousands of lines ...
  very, very, very, very, very, very, very, very, very,
  very, very, very, very, very, very, very, very, long
  multiline comment.

  Bun's lexer now uses SIMD instructions to skip over
  this block of text much faster than before.
*/
console.log("This file now parses much faster!");

改進了對死 try...catch 塊的搖樹最佳化

Bun 的打包器現在可以消除死程式碼路徑中的 try...catch...finally 塊,例如在 return 語句之後。此改進透過更有效地移除無法訪問的程式碼來幫助減小包大小。

// input.js
function test() {
  return "foo";

  // This code is unreachable and will be removed.
  try {
    return "bar";
  } catch (e) {
    console.log(e);
  }
}

// bun build --minify ./input.js
// Before:
function test() {
  return "foo";
  try {
    return "bar";
  } catch (e) {
    console.log(e);
  }
}

// After:
function test() {
  return "foo";
}

感謝 @evanw 的 esbuild 的原始實現。

打包器移除了未使用的 Symbol.for() 呼叫

Bun 的精簡器現在對死程式碼消除更加智慧。未使用的 Symbol.for() 呼叫(使用字串或數字等原始引數)現在已被移除,因為如果結果符號未被使用,它們是無副作用的。這導致包更小。

輸入

input.js
Symbol.for("this will be removed");
const a = Symbol.for("this will be kept");
console.log(a);

輸出

output.js
var o=Symbol.for("this will be kept");console.log(o);

Node.js 相容性改進

v8 C++ API 改進

Bun 對 V8 C++ API 的實現(允許原生 Node.js 外掛在 Bun 中執行)已得到顯著改進。此版本增加了與陣列和物件互動的幾個核心函式的支援,包括 v8::Array::Newv8::Object::Getv8::Object::Setv8::Value::StrictEquals

這將 Bun 的 API 更接近 Node.js v24 的完整 ABI 相容性,這意味著更多原生模組無需重新編譯即可開箱即用。

感謝 @Jarred-Sumner@190n 的貢獻

支援 vm.constants.DONT_CONTEXTIFY

DONT_CONTEXTIFYnode:vm 函式中代替 context 物件傳遞時,新上下文的 globalThis 值將具有較少的特殊行為,並且更像典型的 globalThis,與具有該選項的 Node.js 行為匹配。

import vm from "node:vm";

const contextified = vm.createContext({});
// false: globalThis in child context is a different object than the parent's reference to the context
console.log(vm.runInContext("globalThis", contextified) === contextified);

const notContextified = vm.createContext(vm.constants.DONT_CONTEXTIFY);
// true: parent and child context have the same object
console.log(vm.runInContext("globalThis", notContextified) === notContextified);

感謝 @heimskr 的貢獻!

os.networkInterfaces() 現在正確返回 scopeid

已修復 os.networkInterfaces() 中的一個 bug,該 bug 返回了 IPv6 網路介面的 scope_id 屬性。為了提高與 Node.js 的相容性,此屬性已重新命名為 scopeid

import { networkInterfaces } from "os";

const interfaces = networkInterfaces();

for (const name of Object.keys(interfaces)) {
  for (const net of interfaces[name]) {
    // For IPv6, the `scopeid` property is now correctly named.
    if (net.family === "IPv6") {
      console.log(net.scopeid);
      // => 0 (or another number)

      console.log(net.scope_id);
      // => undefined
    }
  }
}

感謝 @riskymh 的貢獻!

支援 process.features.typescript

為了提高與 Node.js 的相容性,現在實現了 process.features.typescript。此屬性返回字串 "transform",反映了 Bun 的執行時預設情況下會轉譯 TypeScript。此外,還支援 process.features.require_moduleprocess.features.openssl_is_boringssl

console.log(process.features.typescript);
// "transform"

console.log(process.features.require_module);
// true

console.log(process.features.openssl_is_boringssl);
// true

感謝 @riskymh 的貢獻!

fs.glob 現在支援用於模式和 exclude 的陣列

node:fs 模組的 globglobSyncpromises.glob 函式已得到增強,以便更緊密地與 node-glob 對齊。

您現在可以將 glob 模式陣列作為第一個引數傳遞,以同時匹配多個模式。此外,exclude 選項現在接受 glob 模式陣列來過濾結果,為現有的基於函式的過濾提供了一個強大的替代方案。

import { globSync } from "node:fs";
import { mkdirSync, writeFileSync } from "node:fs";

// Create some dummy files for demonstration
mkdirSync("a", { recursive: true });
mkdirSync("b", { recursive: true });
writeFileSync("a/file.js", "");
writeFileSync("a/file.ts", "");
writeFileSync("a/style.css", "");
writeFileSync("b/component.js", "");

// Match all .js and .ts files, but exclude anything in the 'b' directory.
const files = globSync(["**/*.js", "**/*.ts"], {
  ignore: ["b/**"], // or `exclude`
});

console.log(files.sort());
// => ["a/file.js", "a/file.ts"]

感謝 @riskymh 的貢獻!

node:moduleSourceMap 類和 findSourceMap()

Bun 現在實現了 node:module 內建模組中的 SourceMap 類和 findSourceMap() 函式。這允許以程式設計方式解析、檢查和搜尋 sourcemap,提高了與 Node.js 和依賴於此 API 的工具的相容性。

此實現還修復瞭解析包含 names 欄位的 sourcemap 的 bug,並解決了 sourcemap 解析失敗時潛在的記憶體洩漏問題。

import { SourceMap } from "node:module";

const payload = {
  version: 3,
  file: "output.js",
  sources: ["input.js"],
  sourcesContent: ["() => {}"],
  names: ["add"],
  mappings: "AAAA,SAASA,GAAG",
};

const map = new SourceMap(payload);

// The payload getter returns the object used to construct the SourceMap
console.log(map.payload);
// { version: 3, file: 'output.js', ... }

// Find the original source location for a given generated location
const entry = map.findEntry(0, 9);
console.log(entry);
// {
//   generatedLine: 0,
//   generatedColumn: 9,
//   originalLine: 0,
//   originalColumn: 9,
//   originalSource: 'input.js',
//   name: 'add'
// }

@types/bun 變得更智慧

此版本修復了 Bun 內建 TypeScript 型別的一個長期存在的痛點。以前,存在於瀏覽器和 Node.js 類環境中的全域性型別(如 EventSourcePerformanceBroadcastChannel)使用空介面(如 interface EventSource {})進行宣告。這允許它們在您的 tsconfig.json 中包含 "lib": ["dom"] 時與 DOM 的內建型別合併。

但是,如果您包含 DOM 庫,那麼這些介面的任何使用都會顯示為空,沒有任何屬性。

Bun 的型別現在更智慧了。它們會檢測您的 tsconfig.json 中是否包含 "lib": ["dom"],如果沒有,它們會自動從 undici-typesnode:perf_hooksnode:worker_threads 等模組擴充套件相應的 Node.js 相容型別。

感謝 @alii 的貢獻!

Node.js 相容性 bug 修復

  • 現在會尊重 NODE_NO_WARNINGS 環境變數
  • node:http2 不再在應該只發送一個 RST 幀時傳送多個

bun:test bug 修復

  • -t 過濾器現在會隱藏輸出中的跳過和待辦測試
  • 已修復當 beforeEach 鉤子丟擲錯誤時可能導致後續測試名稱被損壞的記憶體損壞問題

執行時 bug 修復

  • 已修復 Bun.which() 中一個罕見的假設性崩潰
  • Request 建構函式現在儲存 redirect 選項,修復了當輸入 Request 在建構函式中傳遞了 redirect: "manual"fetch() 會阻止重定向的 bug。
  • 修復了一個 bug,該 bug 可能在訪問 request.body 後刪除 Content-Type 標頭,當輸入 Request 來自 FormData 物件或來自某些程式碼路徑構造的 ReadableStream 物件時。
  • Bun.inspect 現在顯示 Response 物件的 [檔案大小](當傳遞 Bun.file 時)。
  • 修復了一個 bug,該 bug 可能導致在非常小的應用程式中未被引用的 setTimeoutsetInterval 未被執行
  • 已修復在使用打包器中的 async 宏時可能在 Windows 上發生的崩潰。這影響了 OpenCode。
  • WebSocket 上的 "error" 事件現在包含一個 Error 物件,而不是僅僅一個字串。
  • Bun.S3 預簽名 URL 現在按字母順序對查詢引數進行排序,修復了可能導致無效簽名生成的 bug。
  • fetch() 現在允許使用者覆蓋 Connection 標頭,修復了 fetch() 始終將 Connection 標頭設定為 keep-alive 的 bug。
  • 已修復在從環境變數載入僅限 HTTP 的 S3_ENDPOINT 時 Bun.s3 的 bug。

打包器 bug 修復

  • 修復了一個 bug,該 bug 在引用兄弟作用域中的預設匯出元件時,可能導致 React HMR 出現 "identifier has already been declared" 錯誤。
  • 修復了在使用 onLoad 外掛和 loader: "file" 時可能發生的 bug。
  • 修復了一個 CSS 解析 bug,該 bug 在解析包含 hsl() 的 calc()color-mix() 的 CSS 時可能發生。
  • 修復了一個 bug,當 sourcemap: true 傳遞給 Bun.build 時,sourcemap 不會被生成。以前它只接受字串列舉。

TypeScript 型別改進

  • ReadableStream 現在包含 .text().json().bytes().blob()
  • process.env 型別不再錯誤地繼承自 import.meta.env
  • Bun.serve 的 TypeScript 型別現在正確支援 Bun.file()

bun install bug 修復

  • 已修復在使用某些依賴型別進行 bun install 時,透過 CLI 向專案新增多個軟體包的 bug。
  • bunx yarn 在 Windows 上因不必要的 postinstall 指令碼而失敗的問題已得到解決
  • bun install 的摘要輸出現在被緩衝,這在大規模 monorepos 中使 bun install 速度加快約 20 毫秒
  • 已修復在 bun install 期間因目錄被刪除而導致生命週期指令碼失敗的 bug

bun shell bug修復

  • 已修復在 package.json 指令碼中使用 $ 字首變數的 bug。
  • 已修復因不正確處理 EPIPE 錯誤而導致的 bug。

感謝 18 位貢獻者!