diff --git a/.aikido b/.aikido new file mode 100644 index 0000000000..db335af624 --- /dev/null +++ b/.aikido @@ -0,0 +1,19 @@ +exclude: + paths: + - test + - scripts + - bench + - packages/bun-lambda + - packages/bun-release + - packages/bun-wasm + - packages/bun-vscode + - packages/bun-plugin-yaml + - packages/bun-plugin-svelte + - packages/bun-native-plugin-rs + - packages/bun-native-bundler-plugin-api + - packages/bun-inspector-protocol + - packages/bun-inspector-frontend + - packages/bun-error + - packages/bun-debug-adapter-protocol + - packages/bun-build-mdx-rs + - packages/@types/bun diff --git a/.buildkite/ci.mjs b/.buildkite/ci.mjs index bf346e6c69..1f9168bbe8 100755 --- a/.buildkite/ci.mjs +++ b/.buildkite/ci.mjs @@ -31,7 +31,7 @@ import { } from "../scripts/utils.mjs"; /** - * @typedef {"linux" | "darwin" | "windows"} Os + * @typedef {"linux" | "darwin" | "windows" | "freebsd"} Os * @typedef {"aarch64" | "x64"} Arch * @typedef {"musl"} Abi * @typedef {"debian" | "ubuntu" | "alpine" | "amazonlinux"} Distro @@ -114,6 +114,7 @@ const buildPlatforms = [ { os: "linux", arch: "x64", abi: "musl", baseline: true, distro: "alpine", release: "3.22" }, { os: "windows", arch: "x64", release: "2019" }, { os: "windows", arch: "x64", baseline: true, release: "2019" }, + { os: "freebsd", arch: "x64", release: "14.3" }, ]; /** @@ -124,10 +125,10 @@ const testPlatforms = [ { os: "darwin", arch: "aarch64", release: "13", tier: "previous" }, { os: "darwin", arch: "x64", release: "14", tier: "latest" }, { os: "darwin", arch: "x64", release: "13", tier: "previous" }, - { os: "linux", arch: "aarch64", distro: "debian", release: "12", tier: "latest" }, - { os: "linux", arch: "x64", distro: "debian", release: "12", tier: "latest" }, - { os: "linux", arch: "x64", baseline: true, distro: "debian", release: "12", tier: "latest" }, - { os: "linux", arch: "x64", profile: "asan", distro: "debian", release: "12", tier: "latest" }, + { os: "linux", arch: "aarch64", distro: "debian", release: "13", tier: "latest" }, + { os: "linux", arch: "x64", distro: "debian", release: "13", tier: "latest" }, + { os: "linux", arch: "x64", baseline: true, distro: "debian", release: "13", tier: "latest" }, + { os: "linux", arch: "x64", profile: "asan", distro: "debian", release: "13", tier: "latest" }, { os: "linux", arch: "aarch64", distro: "ubuntu", release: "25.04", tier: "latest" }, { os: "linux", arch: "aarch64", distro: "ubuntu", release: "24.04", tier: "latest" }, { os: "linux", arch: "x64", distro: "ubuntu", release: "25.04", tier: "latest" }, @@ -659,7 +660,7 @@ function getReleaseStep(buildPlatforms, options) { agents: { queue: "test-darwin", }, - depends_on: buildPlatforms.map(platform => `${getTargetKey(platform)}-build-bun`), + depends_on: buildPlatforms.filter(p => p.os !== "freebsd").map(platform => `${getTargetKey(platform)}-build-bun`), env: { CANARY: revision, }, @@ -1072,7 +1073,7 @@ async function getPipeline(options = {}) { const imagePlatforms = new Map( buildImages || publishImages ? [...buildPlatforms, ...testPlatforms] - .filter(({ os }) => os === "linux" || os === "windows") + .filter(({ os }) => os !== "darwin") .map(platform => [getImageKey(platform), platform]) : [], ); @@ -1106,10 +1107,13 @@ async function getPipeline(options = {}) { const includeASAN = !isMainBranch(); if (!buildId) { - const relevantBuildPlatforms = includeASAN + let relevantBuildPlatforms = includeASAN ? buildPlatforms : buildPlatforms.filter(({ profile }) => profile !== "asan"); + // run build-image but no build-bun yet + relevantBuildPlatforms = relevantBuildPlatforms.filter(({ os }) => os !== "freebsd"); + steps.push( ...relevantBuildPlatforms.map(target => { const imageKey = getImageKey(target); diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml deleted file mode 100644 index 3ab51a4309..0000000000 --- a/.github/workflows/claude.yml +++ /dev/null @@ -1,66 +0,0 @@ -name: Claude Code - -on: - issue_comment: - types: [created] - pull_request_review_comment: - types: [created] - issues: - types: [opened, assigned] - pull_request_review: - types: [submitted] - -jobs: - claude: - if: | - github.repository == 'oven-sh/bun' && - ( - (github.event_name == 'issue_comment' && (github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'OWNER' || github.event.comment.author_association == 'COLLABORATOR')) || - (github.event_name == 'pull_request_review_comment' && (github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'OWNER' || github.event.comment.author_association == 'COLLABORATOR')) || - (github.event_name == 'pull_request_review' && (github.event.review.author_association == 'MEMBER' || github.event.review.author_association == 'OWNER' || github.event.review.author_association == 'COLLABORATOR')) || - (github.event_name == 'issues' && (github.event.issue.author_association == 'MEMBER' || github.event.issue.author_association == 'OWNER' || github.event.issue.author_association == 'COLLABORATOR')) - ) && - (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) || - (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || - (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || - (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) - runs-on: claude - env: - IS_SANDBOX: 1 - container: - image: localhost:5000/claude-bun:latest - options: --privileged --user 1000:1000 - permissions: - contents: read - id-token: write - steps: - - name: Checkout repository - working-directory: /workspace/bun - run: | - git config --global user.email "claude-bot@bun.sh" && \ - git config --global user.name "Claude Bot" && \ - git config --global url."git@github.com:".insteadOf "https://github.com/" && \ - git config --global url."git@github.com:".insteadOf "http://github.com/" && \ - git config --global --add safe.directory /workspace/bun && \ - git config --global push.default current && \ - git config --global pull.rebase true && \ - git config --global init.defaultBranch main && \ - git config --global core.editor "vim" && \ - git config --global color.ui auto && \ - git config --global fetch.prune true && \ - git config --global diff.colorMoved zebra && \ - git config --global merge.conflictStyle diff3 && \ - git config --global rerere.enabled true && \ - git config --global core.autocrlf input - git fetch origin ${{ github.event.pull_request.head.sha }} - git checkout ${{ github.event.pull_request.head.ref }} - git reset --hard origin/${{ github.event.pull_request.head.ref }} - - name: Run Claude Code - id: claude - uses: anthropics/claude-code-action@v1 - with: - timeout_minutes: "180" - claude_args: | - --dangerously-skip-permissions - --system-prompt "You are working on the Bun codebase" - claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} diff --git a/.github/workflows/comment-lint.yml b/.github/workflows/comment-lint.yml.disabled similarity index 100% rename from .github/workflows/comment-lint.yml rename to .github/workflows/comment-lint.yml.disabled diff --git a/.github/workflows/labeled.yml b/.github/workflows/labeled.yml.disabled similarity index 100% rename from .github/workflows/labeled.yml rename to .github/workflows/labeled.yml.disabled diff --git a/.vscode/settings.json b/.vscode/settings.json index c2c967c663..826070d42b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -27,18 +27,22 @@ "git.ignoreLimitWarning": true, // Zig - "zig.initialSetupDone": true, - "zig.buildOption": "build", + // "zig.initialSetupDone": true, + // "zig.buildOption": "build", "zig.zls.zigLibPath": "${workspaceFolder}/vendor/zig/lib", - "zig.buildArgs": ["-Dgenerated-code=./build/debug/codegen", "--watch", "-fincremental"], - "zig.zls.buildOnSaveStep": "check", + "zig.buildOnSaveArgs": [ + "-Dgenerated-code=./build/debug/codegen", + "--watch", + "-fincremental" + ], + // "zig.zls.buildOnSaveStep": "check", // "zig.zls.enableBuildOnSave": true, // "zig.buildOnSave": true, - "zig.buildFilePath": "${workspaceFolder}/build.zig", + // "zig.buildFilePath": "${workspaceFolder}/build.zig", "zig.path": "${workspaceFolder}/vendor/zig/zig.exe", "zig.zls.path": "${workspaceFolder}/vendor/zig/zls.exe", "zig.formattingProvider": "zls", - "zig.zls.enableInlayHints": false, + // "zig.zls.enableInlayHints": false, "[zig]": { "editor.tabSize": 4, "editor.useTabStops": false, diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9d7785abb1..192ce5ad63 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -201,7 +201,7 @@ Bun generally takes about 2.5 minutes to compile a debug build when there are Zi - Batch up your changes - Ensure zls is running with incremental watching for LSP errors (if you use VSCode and install Zig and run `bun run build` once to download Zig, this should just work) - Prefer using the debugger ("CodeLLDB" in VSCode) to step through the code. -- Use debug logs. `BUN_DEBUG_=1` will enable debug logging for the corresponding `Output.scoped(., .hidden)` logs. You can also set `BUN_DEBUG_QUIET_LOGS=1` to disable all debug logging that isn't explicitly enabled. To dump debug lgos into a file, `BUN_DEBUG=.log`. Debug logs are aggressively removed in release builds. +- Use debug logs. `BUN_DEBUG_=1` will enable debug logging for the corresponding `Output.scoped(., .hidden)` logs. You can also set `BUN_DEBUG_QUIET_LOGS=1` to disable all debug logging that isn't explicitly enabled. To dump debug logs into a file, `BUN_DEBUG=.log`. Debug logs are aggressively removed in release builds. - src/js/\*\*.ts changes are pretty much instant to rebuild. C++ changes are a bit slower, but still much faster than the Zig code (Zig is one compilation unit, C++ is many). ## Code generation scripts diff --git a/LATEST b/LATEST index 1892b92676..31e5c84349 100644 --- a/LATEST +++ b/LATEST @@ -1 +1 @@ -1.3.2 +1.3.3 diff --git a/README.md b/README.md index 36bc7b6953..b12c3807bb 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ Bun supports Linux (x64 & arm64), macOS (x64 & Apple Silicon) and Windows (x64). curl -fsSL https://bun.com/install | bash # on windows -powershell -c "irm bun.com/install.ps1 | iex" +powershell -c "irm bun.sh/install.ps1 | iex" # with npm npm install -g bun @@ -104,13 +104,13 @@ bun upgrade --canary - [File types (Loaders)](https://bun.com/docs/runtime/loaders) - [TypeScript](https://bun.com/docs/typescript) - [JSX](https://bun.com/docs/runtime/jsx) - - [Environment variables](https://bun.com/docs/runtime/env) + - [Environment variables](https://bun.com/docs/runtime/environment-variables) - [Bun APIs](https://bun.com/docs/runtime/bun-apis) - [Web APIs](https://bun.com/docs/runtime/web-apis) - - [Node.js compatibility](https://bun.com/docs/runtime/nodejs-apis) + - [Node.js compatibility](https://bun.com/docs/runtime/nodejs-compat) - [Single-file executable](https://bun.com/docs/bundler/executables) - [Plugins](https://bun.com/docs/runtime/plugins) - - [Watch mode / Hot Reloading](https://bun.com/docs/runtime/hot) + - [Watch mode / Hot Reloading](https://bun.com/docs/runtime/watch-mode) - [Module resolution](https://bun.com/docs/runtime/modules) - [Auto-install](https://bun.com/docs/runtime/autoimport) - [bunfig.toml](https://bun.com/docs/runtime/bunfig) diff --git a/bench/runner.mjs b/bench/runner.mjs index 9f6bcee16f..b9715232f0 100644 --- a/bench/runner.mjs +++ b/bench/runner.mjs @@ -13,7 +13,4 @@ export function run(opts = {}) { } export const bench = Mitata.bench; - -export function group(_name, fn) { - return Mitata.group(fn); -} +export const group = Mitata.group; diff --git a/bench/snippets/compression-streams.mjs b/bench/snippets/compression-streams.mjs new file mode 100644 index 0000000000..b8f3d34cd5 --- /dev/null +++ b/bench/snippets/compression-streams.mjs @@ -0,0 +1,156 @@ +import { bench, group, run } from "../runner.mjs"; + +const runAll = !process.argv.includes("--simple"); + +const small = new Uint8Array(1024); +const medium = new Uint8Array(1024 * 100); +const large = new Uint8Array(1024 * 1024); + +for (let i = 0; i < large.length; i++) { + const value = Math.floor(Math.sin(i / 100) * 128 + 128); + if (i < small.length) small[i] = value; + if (i < medium.length) medium[i] = value; + large[i] = value; +} + +const format = new Intl.NumberFormat("en-US", { notation: "compact", unit: "byte" }); + +async function compress(data, format) { + const cs = new CompressionStream(format); + const writer = cs.writable.getWriter(); + const reader = cs.readable.getReader(); + + writer.write(data); + writer.close(); + + const chunks = []; + while (true) { + const { done, value } = await reader.read(); + if (done) break; + chunks.push(value); + } + + const result = new Uint8Array(chunks.reduce((acc, chunk) => acc + chunk.length, 0)); + let offset = 0; + for (const chunk of chunks) { + result.set(chunk, offset); + offset += chunk.length; + } + return result; +} + +async function decompress(data, format) { + const ds = new DecompressionStream(format); + const writer = ds.writable.getWriter(); + const reader = ds.readable.getReader(); + + writer.write(data); + writer.close(); + + const chunks = []; + while (true) { + const { done, value } = await reader.read(); + if (done) break; + chunks.push(value); + } + + const result = new Uint8Array(chunks.reduce((acc, chunk) => acc + chunk.length, 0)); + let offset = 0; + for (const chunk of chunks) { + result.set(chunk, offset); + offset += chunk.length; + } + return result; +} + +async function roundTrip(data, format) { + const compressed = await compress(data, format); + return await decompress(compressed, format); +} + +const formats = ["deflate", "gzip", "deflate-raw"]; +if (runAll) formats.push("brotli", "zstd"); + +// Small data benchmarks (1KB) +group(`CompressionStream ${format.format(small.length)}`, () => { + for (const fmt of formats) { + try { + new CompressionStream(fmt); + bench(fmt, async () => await compress(small, fmt)); + } catch (e) { + // Skip unsupported formats + } + } +}); + +// Medium data benchmarks (100KB) +group(`CompressionStream ${format.format(medium.length)}`, () => { + for (const fmt of formats) { + try { + new CompressionStream(fmt); + bench(fmt, async () => await compress(medium, fmt)); + } catch (e) {} + } +}); + +// Large data benchmarks (1MB) +group(`CompressionStream ${format.format(large.length)}`, () => { + for (const fmt of formats) { + try { + new CompressionStream(fmt); + bench(fmt, async () => await compress(large, fmt)); + } catch (e) { + // Skip unsupported formats + } + } +}); + +const compressedData = {}; +for (const fmt of formats) { + try { + compressedData[fmt] = { + small: await compress(small, fmt), + medium: await compress(medium, fmt), + large: await compress(large, fmt), + }; + } catch (e) { + // Skip unsupported formats + } +} + +group(`DecompressionStream ${format.format(small.length)}`, () => { + for (const fmt of formats) { + if (compressedData[fmt]) { + bench(fmt, async () => await decompress(compressedData[fmt].small, fmt)); + } + } +}); + +group(`DecompressionStream ${format.format(medium.length)}`, () => { + for (const fmt of formats) { + if (compressedData[fmt]) { + bench(fmt, async () => await decompress(compressedData[fmt].medium, fmt)); + } + } +}); + +group(`DecompressionStream ${format.format(large.length)}`, () => { + for (const fmt of formats) { + if (compressedData[fmt]) { + bench(fmt, async () => await decompress(compressedData[fmt].large, fmt)); + } + } +}); + +group(`roundtrip ${format.format(large.length)}`, () => { + for (const fmt of formats) { + try { + new CompressionStream(fmt); + bench(fmt, async () => await roundTrip(large, fmt)); + } catch (e) { + // Skip unsupported formats + } + } +}); + +await run(); diff --git a/bench/snippets/urlpattern.js b/bench/snippets/urlpattern.js new file mode 100644 index 0000000000..b5e4908c89 --- /dev/null +++ b/bench/snippets/urlpattern.js @@ -0,0 +1,48 @@ +import { bench, group, run } from "../runner.mjs"; + +const patterns = [ + { name: "string pattern", input: "https://(sub.)?example(.com/)foo" }, + { name: "hostname IDN", input: { hostname: "xn--caf-dma.com" } }, + { + name: "pathname + search + hash + baseURL", + input: { + pathname: "/foo", + search: "bar", + hash: "baz", + baseURL: "https://example.com:8080", + }, + }, + { name: "pathname with regex", input: { pathname: "/([[a-z]--a])" } }, + { name: "named groups", input: { pathname: "/users/:id/posts/:postId" } }, + { name: "wildcard", input: { pathname: "/files/*" } }, +]; + +const testURL = "https://sub.example.com/foo"; + +group("URLPattern parse (constructor)", () => { + for (const { name, input } of patterns) { + bench(name, () => { + return new URLPattern(input); + }); + } +}); + +group("URLPattern.test()", () => { + for (const { name, input } of patterns) { + const pattern = new URLPattern(input); + bench(name, () => { + return pattern.test(testURL); + }); + } +}); + +group("URLPattern.exec()", () => { + for (const { name, input } of patterns) { + const pattern = new URLPattern(input); + bench(name, () => { + return pattern.exec(testURL); + }); + } +}); + +await run(); diff --git a/build.zig b/build.zig index eb16d47401..3b50fd1fbe 100644 --- a/build.zig +++ b/build.zig @@ -32,6 +32,7 @@ const BunBuildOptions = struct { /// enable debug logs in release builds enable_logs: bool = false, enable_asan: bool, + enable_fuzzilli: bool, enable_valgrind: bool, use_mimalloc: bool, tracy_callstack_depth: u16, @@ -81,6 +82,7 @@ const BunBuildOptions = struct { opts.addOption(bool, "baseline", this.isBaseline()); opts.addOption(bool, "enable_logs", this.enable_logs); opts.addOption(bool, "enable_asan", this.enable_asan); + opts.addOption(bool, "enable_fuzzilli", this.enable_fuzzilli); opts.addOption(bool, "enable_valgrind", this.enable_valgrind); opts.addOption(bool, "use_mimalloc", this.use_mimalloc); opts.addOption([]const u8, "reported_nodejs_version", b.fmt("{f}", .{this.reported_nodejs_version})); @@ -255,6 +257,7 @@ pub fn build(b: *Build) !void { .tracy_callstack_depth = b.option(u16, "tracy_callstack_depth", "") orelse 10, .enable_logs = b.option(bool, "enable_logs", "Enable logs in release") orelse false, .enable_asan = b.option(bool, "enable_asan", "Enable asan") orelse false, + .enable_fuzzilli = b.option(bool, "enable_fuzzilli", "Enable fuzzilli instrumentation") orelse false, .enable_valgrind = b.option(bool, "enable_valgrind", "Enable valgrind") orelse false, .use_mimalloc = b.option(bool, "use_mimalloc", "Use mimalloc as default allocator") orelse false, .llvm_codegen_threads = b.option(u32, "llvm_codegen_threads", "Number of threads to use for LLVM codegen") orelse 1, @@ -490,6 +493,7 @@ fn addMultiCheck( .no_llvm = root_build_options.no_llvm, .enable_asan = root_build_options.enable_asan, .enable_valgrind = root_build_options.enable_valgrind, + .enable_fuzzilli = root_build_options.enable_fuzzilli, .use_mimalloc = root_build_options.use_mimalloc, .override_no_export_cpp_apis = root_build_options.override_no_export_cpp_apis, }; @@ -605,13 +609,20 @@ fn configureObj(b: *Build, opts: *BunBuildOptions, obj: *Compile) void { obj.no_link_obj = opts.os != .windows; + if (opts.enable_asan and !enableFastBuild(b)) { if (@hasField(Build.Module, "sanitize_address")) { + if (opts.enable_fuzzilli) { + obj.sanitize_coverage_trace_pc_guard = true; + } obj.root_module.sanitize_address = true; } else { const fail_step = b.addFail("asan is not supported on this platform"); obj.step.dependOn(&fail_step.step); } + } else if (opts.enable_fuzzilli) { + const fail_step = b.addFail("fuzzilli requires asan"); + obj.step.dependOn(&fail_step.step); } obj.bundle_compiler_rt = false; obj.bundle_ubsan_rt = false; diff --git a/bun.lock b/bun.lock index e3d7fb8ecd..ee176bb927 100644 --- a/bun.lock +++ b/bun.lock @@ -1,6 +1,6 @@ { "lockfileVersion": 1, - "configVersion": 0, + "configVersion": 1, "workspaces": { "": { "name": "bun", @@ -85,13 +85,13 @@ "@esbuild/win32-x64": ["@esbuild/win32-x64@0.21.5", "", { "os": "win32", "cpu": "x64" }, "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw=="], - "@lezer/common": ["@lezer/common@1.2.3", "", {}, "sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA=="], + "@lezer/common": ["@lezer/common@1.3.0", "", {}, "sha512-L9X8uHCYU310o99L3/MpJKYxPzXPOS7S0NmBaM7UO/x2Kb2WbmMLSkfvdr1KxRIFYOpbY0Jhn7CfLSUDzL8arQ=="], "@lezer/cpp": ["@lezer/cpp@1.1.3", "", { "dependencies": { "@lezer/common": "^1.2.0", "@lezer/highlight": "^1.0.0", "@lezer/lr": "^1.0.0" } }, "sha512-ykYvuFQKGsRi6IcE+/hCSGUhb/I4WPjd3ELhEblm2wS2cOznDFzO+ubK2c+ioysOnlZ3EduV+MVQFCPzAIoY3w=="], - "@lezer/highlight": ["@lezer/highlight@1.2.1", "", { "dependencies": { "@lezer/common": "^1.0.0" } }, "sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA=="], + "@lezer/highlight": ["@lezer/highlight@1.2.3", "", { "dependencies": { "@lezer/common": "^1.3.0" } }, "sha512-qXdH7UqTvGfdVBINrgKhDsVTJTxactNNxLk7+UMwZhU13lMHaOBlJe9Vqp907ya56Y3+ed2tlqzys7jDkTmW0g=="], - "@lezer/lr": ["@lezer/lr@1.4.2", "", { "dependencies": { "@lezer/common": "^1.0.0" } }, "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA=="], + "@lezer/lr": ["@lezer/lr@1.4.3", "", { "dependencies": { "@lezer/common": "^1.0.0" } }, "sha512-yenN5SqAxAPv/qMnpWW0AT7l+SxVrgG+u0tNsRQWqbrz66HIl8DnEbBObvy21J5K7+I1v7gsAnlE2VQ5yYVSeA=="], "@octokit/app": ["@octokit/app@14.1.0", "", { "dependencies": { "@octokit/auth-app": "^6.0.0", "@octokit/auth-unauthenticated": "^5.0.0", "@octokit/core": "^5.0.0", "@octokit/oauth-app": "^6.0.0", "@octokit/plugin-paginate-rest": "^9.0.0", "@octokit/types": "^12.0.0", "@octokit/webhooks": "^12.0.4" } }, "sha512-g3uEsGOQCBl1+W1rgfwoRFUIR6PtvB2T1E4RpygeUU5LrLvlOqcxrt5lfykIeRpUPpupreGJUYl70fqMDXdTpw=="], @@ -145,7 +145,7 @@ "@sentry/types": ["@sentry/types@7.120.4", "", {}, "sha512-cUq2hSSe6/qrU6oZsEP4InMI5VVdD86aypE+ENrQ6eZEVLTCYm1w6XhW1NvIu3UuWh7gZec4a9J7AFpYxki88Q=="], - "@types/aws-lambda": ["@types/aws-lambda@8.10.152", "", {}, "sha512-soT/c2gYBnT5ygwiHPmd9a1bftj462NWVk2tKCc1PYHSIacB2UwbTS2zYG4jzag1mRDuzg/OjtxQjQ2NKRB6Rw=="], + "@types/aws-lambda": ["@types/aws-lambda@8.10.159", "", {}, "sha512-SAP22WSGNN12OQ8PlCzGzRCZ7QDCwI85dQZbmpz7+mAk+L7j+wI7qnvmdKh+o7A5LaOp6QnOZ2NJphAZQTTHQg=="], "@types/btoa-lite": ["@types/btoa-lite@1.0.2", "", {}, "sha512-ZYbcE2x7yrvNFJiU7xJGrpF/ihpkM7zKgw8bha3LNJSesvTtUNxbpzaT7WXBIryf6jovisrxTBvymxMeLLj1Mg=="], @@ -155,7 +155,7 @@ "@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="], - "@types/node": ["@types/node@24.2.1", "", { "dependencies": { "undici-types": "~7.10.0" } }, "sha512-DRh5K+ka5eJic8CjH7td8QpYEV6Zo10gfRkjHCO3weqZHWDtAaSTFtl4+VMqOJ4N5jcuhZ9/l+yy8rVgw7BQeQ=="], + "@types/node": ["@types/node@24.10.1", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ=="], "aggregate-error": ["aggregate-error@3.1.0", "", { "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" } }, "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA=="], @@ -187,7 +187,7 @@ "deprecation": ["deprecation@2.3.1", "", {}, "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="], - "detect-libc": ["detect-libc@2.0.4", "", {}, "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA=="], + "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], "dot-case": ["dot-case@3.0.4", "", { "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3" } }, "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w=="], @@ -211,27 +211,29 @@ "jws": ["jws@3.2.2", "", { "dependencies": { "jwa": "^1.4.1", "safe-buffer": "^5.0.1" } }, "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA=="], - "lightningcss": ["lightningcss@1.30.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-darwin-arm64": "1.30.1", "lightningcss-darwin-x64": "1.30.1", "lightningcss-freebsd-x64": "1.30.1", "lightningcss-linux-arm-gnueabihf": "1.30.1", "lightningcss-linux-arm64-gnu": "1.30.1", "lightningcss-linux-arm64-musl": "1.30.1", "lightningcss-linux-x64-gnu": "1.30.1", "lightningcss-linux-x64-musl": "1.30.1", "lightningcss-win32-arm64-msvc": "1.30.1", "lightningcss-win32-x64-msvc": "1.30.1" } }, "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg=="], + "lightningcss": ["lightningcss@1.30.2", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.30.2", "lightningcss-darwin-arm64": "1.30.2", "lightningcss-darwin-x64": "1.30.2", "lightningcss-freebsd-x64": "1.30.2", "lightningcss-linux-arm-gnueabihf": "1.30.2", "lightningcss-linux-arm64-gnu": "1.30.2", "lightningcss-linux-arm64-musl": "1.30.2", "lightningcss-linux-x64-gnu": "1.30.2", "lightningcss-linux-x64-musl": "1.30.2", "lightningcss-win32-arm64-msvc": "1.30.2", "lightningcss-win32-x64-msvc": "1.30.2" } }, "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ=="], - "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.30.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ=="], + "lightningcss-android-arm64": ["lightningcss-android-arm64@1.30.2", "", { "os": "android", "cpu": "arm64" }, "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A=="], - "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.30.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA=="], + "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.30.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA=="], - "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.30.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig=="], + "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.30.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ=="], - "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.30.1", "", { "os": "linux", "cpu": "arm" }, "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q=="], + "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.30.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA=="], - "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.30.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw=="], + "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.30.2", "", { "os": "linux", "cpu": "arm" }, "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA=="], - "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.30.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ=="], + "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.30.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A=="], - "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.30.1", "", { "os": "linux", "cpu": "x64" }, "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw=="], + "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.30.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA=="], - "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.30.1", "", { "os": "linux", "cpu": "x64" }, "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ=="], + "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.30.2", "", { "os": "linux", "cpu": "x64" }, "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w=="], - "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.30.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA=="], + "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.30.2", "", { "os": "linux", "cpu": "x64" }, "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA=="], - "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.30.1", "", { "os": "win32", "cpu": "x64" }, "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg=="], + "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.30.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ=="], + + "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.30.2", "", { "os": "win32", "cpu": "x64" }, "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw=="], "lodash.includes": ["lodash.includes@4.3.0", "", {}, "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="], @@ -287,7 +289,7 @@ "scheduler": ["scheduler@0.23.2", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ=="], - "semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="], + "semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], "sentence-case": ["sentence-case@3.0.4", "", { "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3", "upper-case-first": "^2.0.2" } }, "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg=="], @@ -303,7 +305,7 @@ "uglify-js": ["uglify-js@3.19.3", "", { "bin": { "uglifyjs": "bin/uglifyjs" } }, "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ=="], - "undici-types": ["undici-types@7.10.0", "", {}, "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag=="], + "undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], "universal-github-app-jwt": ["universal-github-app-jwt@1.2.0", "", { "dependencies": { "@types/jsonwebtoken": "^9.0.0", "jsonwebtoken": "^9.0.2" } }, "sha512-dncpMpnsKBk0eetwfN8D8OUHGfiDhhJ+mtsbMl+7PfW7mYjiH8LIcqRmYMtzYLgSh47HjfdBtrBwIQ/gizKR3g=="], diff --git a/bunfig.toml b/bunfig.toml index f1bba3259c..82329b401e 100644 --- a/bunfig.toml +++ b/bunfig.toml @@ -10,4 +10,4 @@ preload = "./test/preload.ts" [install] linker = "isolated" -minimumReleaseAge = 1 +minimumReleaseAge = 259200 # three days diff --git a/cmake/CompilerFlags.cmake b/cmake/CompilerFlags.cmake index cff32fb166..bff19e1974 100644 --- a/cmake/CompilerFlags.cmake +++ b/cmake/CompilerFlags.cmake @@ -51,6 +51,23 @@ if(ENABLE_ASAN) ) endif() +if(ENABLE_FUZZILLI) + register_compiler_flags( + DESCRIPTION "Enable coverage instrumentation for fuzzing" + -fsanitize-coverage=trace-pc-guard + ) + + register_linker_flags( + DESCRIPTION "Link coverage instrumentation" + -fsanitize-coverage=trace-pc-guard + ) + + register_compiler_flags( + DESCRIPTION "Enable fuzzilli-specific code" + -DFUZZILLI_ENABLED + ) +endif() + # --- Optimization level --- if(DEBUG) register_compiler_flags( diff --git a/cmake/Options.cmake b/cmake/Options.cmake index ac6ce10c74..e54f6db166 100644 --- a/cmake/Options.cmake +++ b/cmake/Options.cmake @@ -127,6 +127,8 @@ if (NOT ENABLE_ASAN) set(ENABLE_ZIG_ASAN OFF) endif() +optionx(ENABLE_FUZZILLI BOOL "If fuzzilli support should be enabled" DEFAULT OFF) + if(RELEASE AND LINUX AND CI AND NOT ENABLE_ASSERTIONS AND NOT ENABLE_ASAN) set(DEFAULT_LTO ON) else() diff --git a/cmake/analysis/RunClangFormat.cmake b/cmake/analysis/RunClangFormat.cmake index 106ac54ef6..f290116b53 100644 --- a/cmake/analysis/RunClangFormat.cmake +++ b/cmake/analysis/RunClangFormat.cmake @@ -34,26 +34,6 @@ register_command( ALWAYS_RUN ) -if(GIT_CHANGED_SOURCES) - set(CLANG_FORMAT_CHANGED_SOURCES) - foreach(source ${CLANG_FORMAT_SOURCES}) - list(FIND GIT_CHANGED_SOURCES ${source} index) - if(NOT ${index} EQUAL -1) - list(APPEND CLANG_FORMAT_CHANGED_SOURCES ${source}) - endif() - endforeach() -endif() - -if(CLANG_FORMAT_CHANGED_SOURCES) - set(CLANG_FORMAT_DIFF_COMMAND ${CLANG_FORMAT_PROGRAM} - -i # edits files in-place - --verbose - ${CLANG_FORMAT_CHANGED_SOURCES} - ) -else() - set(CLANG_FORMAT_DIFF_COMMAND ${CMAKE_COMMAND} -E echo "No changed files for clang-format") -endif() - register_command( TARGET clang-format-diff diff --git a/cmake/analysis/RunClangTidy.cmake b/cmake/analysis/RunClangTidy.cmake index ee5782ade8..23e1422c27 100644 --- a/cmake/analysis/RunClangTidy.cmake +++ b/cmake/analysis/RunClangTidy.cmake @@ -3,7 +3,7 @@ set(CLANG_TIDY_SOURCES ${BUN_C_SOURCES} ${BUN_CXX_SOURCES}) set(CLANG_TIDY_COMMAND ${CLANG_TIDY_PROGRAM} - -p ${BUILD_PATH} + -p ${BUILD_PATH} --config-file=${CWD}/.clang-tidy ) @@ -40,27 +40,6 @@ register_command( ALWAYS_RUN ) -if(GIT_CHANGED_SOURCES) - set(CLANG_TIDY_CHANGED_SOURCES) - foreach(source ${CLANG_TIDY_SOURCES}) - list(FIND GIT_CHANGED_SOURCES ${source} index) - if(NOT ${index} EQUAL -1) - list(APPEND CLANG_TIDY_CHANGED_SOURCES ${source}) - endif() - endforeach() -endif() - -if(CLANG_TIDY_CHANGED_SOURCES) - set(CLANG_TIDY_DIFF_COMMAND ${CLANG_TIDY_PROGRAM} - ${CLANG_TIDY_CHANGED_SOURCES} - --fix - --fix-errors - --fix-notes - ) -else() - set(CLANG_TIDY_DIFF_COMMAND ${CMAKE_COMMAND} -E echo "No changed files for clang-tidy") -endif() - register_command( TARGET clang-tidy-diff diff --git a/cmake/analysis/RunPrettier.cmake b/cmake/analysis/RunPrettier.cmake index 8c8ceb1ba1..55122f1854 100644 --- a/cmake/analysis/RunPrettier.cmake +++ b/cmake/analysis/RunPrettier.cmake @@ -92,26 +92,6 @@ register_command( ALWAYS_RUN ) -if(GIT_CHANGED_SOURCES) - set(PRETTIER_CHANGED_SOURCES) - foreach(source ${PRETTIER_SOURCES}) - list(FIND GIT_CHANGED_SOURCES ${source} index) - if(NOT ${index} EQUAL -1) - list(APPEND PRETTIER_CHANGED_SOURCES ${source}) - endif() - endforeach() -endif() - -if(PRETTIER_CHANGED_SOURCES) - set(PRETTIER_DIFF_COMMAND ${PRETTIER_COMMAND} - --write - --plugin=prettier-plugin-organize-imports - ${PRETTIER_CHANGED_SOURCES} - ) -else() - set(PRETTIER_DIFF_COMMAND ${CMAKE_COMMAND} -E echo "No changed files for prettier") -endif() - register_command( TARGET prettier-diff diff --git a/cmake/analysis/RunZigFormat.cmake b/cmake/analysis/RunZigFormat.cmake index 0ff7c23865..9486eb4368 100644 --- a/cmake/analysis/RunZigFormat.cmake +++ b/cmake/analysis/RunZigFormat.cmake @@ -25,25 +25,6 @@ register_command( ALWAYS_RUN ) -if(GIT_CHANGED_SOURCES) - set(ZIG_FORMAT_CHANGED_SOURCES) - foreach(source ${ZIG_FORMAT_SOURCES}) - list(FIND GIT_CHANGED_SOURCES ${source} index) - if(NOT ${index} EQUAL -1) - list(APPEND ZIG_FORMAT_CHANGED_SOURCES ${source}) - endif() - endforeach() -endif() - -if(ZIG_FORMAT_CHANGED_SOURCES) - set(ZIG_FORMAT_DIFF_COMMAND ${ZIG_EXECUTABLE} - fmt - ${ZIG_FORMAT_CHANGED_SOURCES} - ) -else() - set(ZIG_FORMAT_DIFF_COMMAND ${CMAKE_COMMAND} -E echo "No changed files for zig-format") -endif() - register_command( TARGET zig-format-diff diff --git a/cmake/targets/BuildBun.cmake b/cmake/targets/BuildBun.cmake index 43b061846b..6b23266ade 100644 --- a/cmake/targets/BuildBun.cmake +++ b/cmake/targets/BuildBun.cmake @@ -695,6 +695,7 @@ register_command( -Dcpu=${ZIG_CPU} -Denable_logs=$,true,false> -Denable_asan=$,true,false> + -Denable_fuzzilli=$,true,false> -Denable_valgrind=$,true,false> -Duse_mimalloc=$,true,false> -Dllvm_codegen_threads=${LLVM_ZIG_CODEGEN_THREADS} diff --git a/cmake/tools/SetupGit.cmake b/cmake/tools/SetupGit.cmake index 7f28fe7743..5e084991a7 100644 --- a/cmake/tools/SetupGit.cmake +++ b/cmake/tools/SetupGit.cmake @@ -4,41 +4,9 @@ find_command( COMMAND git REQUIRED - OFF + ${CI} ) if(NOT GIT_PROGRAM) return() endif() - -set(GIT_DIFF_COMMAND ${GIT_PROGRAM} diff --no-color --name-only --diff-filter=AMCR origin/main HEAD) - -execute_process( - COMMAND - ${GIT_DIFF_COMMAND} - WORKING_DIRECTORY - ${CWD} - OUTPUT_STRIP_TRAILING_WHITESPACE - OUTPUT_VARIABLE - GIT_DIFF - ERROR_STRIP_TRAILING_WHITESPACE - ERROR_VARIABLE - GIT_DIFF_ERROR - RESULT_VARIABLE - GIT_DIFF_RESULT -) - -if(NOT GIT_DIFF_RESULT EQUAL 0) - message(WARNING "Command failed: ${GIT_DIFF_COMMAND} ${GIT_DIFF_ERROR}") - return() -endif() - -string(REPLACE "\n" ";" GIT_CHANGED_SOURCES "${GIT_DIFF}") - -if(CI) - set(GIT_CHANGED_SOURCES "${GIT_CHANGED_SOURCES}") - message(STATUS "Set GIT_CHANGED_SOURCES: ${GIT_CHANGED_SOURCES}") -endif() - -list(TRANSFORM GIT_CHANGED_SOURCES PREPEND ${CWD}/) -list(LENGTH GIT_CHANGED_SOURCES GIT_CHANGED_SOURCES_COUNT) diff --git a/cmake/tools/SetupZig.cmake b/cmake/tools/SetupZig.cmake index 1de53f05e3..320a6f4e64 100644 --- a/cmake/tools/SetupZig.cmake +++ b/cmake/tools/SetupZig.cmake @@ -55,13 +55,7 @@ optionx(ZIG_OBJECT_FORMAT "obj|bc" "Output file format for Zig object files" DEF optionx(ZIG_LOCAL_CACHE_DIR FILEPATH "The path to local the zig cache directory" DEFAULT ${CACHE_PATH}/zig/local) optionx(ZIG_GLOBAL_CACHE_DIR FILEPATH "The path to the global zig cache directory" DEFAULT ${CACHE_PATH}/zig/global) -if(CI) - set(ZIG_COMPILER_SAFE_DEFAULT ON) -else() - set(ZIG_COMPILER_SAFE_DEFAULT OFF) -endif() - -optionx(ZIG_COMPILER_SAFE BOOL "Download a ReleaseSafe build of the Zig compiler." DEFAULT ${ZIG_COMPILER_SAFE_DEFAULT}) +optionx(ZIG_COMPILER_SAFE BOOL "Download a ReleaseSafe build of the Zig compiler." DEFAULT ${CI}) setenv(ZIG_LOCAL_CACHE_DIR ${ZIG_LOCAL_CACHE_DIR}) setenv(ZIG_GLOBAL_CACHE_DIR ${ZIG_GLOBAL_CACHE_DIR}) diff --git a/dockerhub/debian-slim/Dockerfile b/dockerhub/debian-slim/Dockerfile index 755a8415ca..996034f9ca 100644 --- a/dockerhub/debian-slim/Dockerfile +++ b/dockerhub/debian-slim/Dockerfile @@ -1,4 +1,4 @@ -FROM debian:bookworm-slim AS build +FROM debian:trixie-slim AS build # https://github.com/oven-sh/bun/releases ARG BUN_VERSION=latest @@ -55,7 +55,7 @@ RUN apt-get update -qq \ && which bun \ && bun --version -FROM debian:bookworm-slim +FROM debian:trixie-slim # Disable the runtime transpiler cache by default inside Docker containers. # On ephemeral containers, the cache is not useful diff --git a/dockerhub/debian/Dockerfile b/dockerhub/debian/Dockerfile index f8ed38c3c5..85a9250d9a 100644 --- a/dockerhub/debian/Dockerfile +++ b/dockerhub/debian/Dockerfile @@ -1,4 +1,4 @@ -FROM debian:bookworm-slim AS build +FROM debian:trixie-slim AS build # https://github.com/oven-sh/bun/releases ARG BUN_VERSION=latest @@ -56,7 +56,7 @@ RUN apt-get update -qq \ && rm -f "bun-linux-$build.zip" SHASUMS256.txt.asc SHASUMS256.txt \ && chmod +x /usr/local/bin/bun -FROM debian:bookworm +FROM debian:trixie COPY docker-entrypoint.sh /usr/local/bin COPY --from=build /usr/local/bin/bun /usr/local/bin/bun diff --git a/dockerhub/distroless/Dockerfile b/dockerhub/distroless/Dockerfile index 32c8a0f99a..cb5f9a7292 100644 --- a/dockerhub/distroless/Dockerfile +++ b/dockerhub/distroless/Dockerfile @@ -1,4 +1,4 @@ -FROM debian:bookworm-slim AS build +FROM debian:trixie-slim AS build # https://github.com/oven-sh/bun/releases ARG BUN_VERSION=latest @@ -55,7 +55,7 @@ RUN apt-get update -qq \ && which bun \ && bun --version -FROM gcr.io/distroless/base-nossl-debian11 +FROM gcr.io/distroless/base-nossl-debian13 # Disable the runtime transpiler cache by default inside Docker containers. # On ephemeral containers, the cache is not useful diff --git a/docs/bundler/css.mdx b/docs/bundler/css.mdx index 730332f173..7a73280b79 100644 --- a/docs/bundler/css.mdx +++ b/docs/bundler/css.mdx @@ -72,7 +72,7 @@ Bun's CSS bundler automatically converts this nested syntax into traditional fla You can also nest media queries and other at-rules inside selectors, eliminating the need to repeat selector patterns: -```css title="styles.css" icon="file-code" +```scss title="styles.css" icon="file-code" .responsive-element { display: block; diff --git a/docs/bundler/executables.mdx b/docs/bundler/executables.mdx index 79e6d6a55e..71b3386a4b 100644 --- a/docs/bundler/executables.mdx +++ b/docs/bundler/executables.mdx @@ -90,7 +90,7 @@ The order of the `--target` flag does not matter, as long as they're delimited b | bun-linux-x64 | Linux | x64 | ✅ | ✅ | glibc | | bun-linux-arm64 | Linux | arm64 | ✅ | N/A | glibc | | bun-windows-x64 | Windows | x64 | ✅ | ✅ | - | -| ~~bun-windows-arm64~~ | Windows | arm64 | ❌ | ❌ | - | +| ~~bun-windows-arm64~~ | ~~Windows~~ | ~~arm64~~ | ❌ | ❌ | - | | bun-darwin-x64 | macOS | x64 | ✅ | ✅ | - | | bun-darwin-arm64 | macOS | arm64 | ✅ | N/A | - | | bun-linux-x64-musl | Linux | x64 | ✅ | ✅ | musl | @@ -118,7 +118,7 @@ These constants are embedded directly into your compiled binary at build time, p For comprehensive examples and advanced patterns, see the [Build-time constants - guide](https://bun.com/guides/runtime/build-time-constants). + guide](/guides/runtime/build-time-constants). --- @@ -183,6 +183,35 @@ console.log(process.execArgv); // ["--smol", "--user-agent=MyBot"] --- +## Disabling automatic config loading + +By default, standalone executables look for `.env` and `bunfig.toml` files in the directory where the executable is run. You can disable this behavior at build time for deterministic execution regardless of the user's working directory. + +```bash icon="terminal" terminal +# Disable .env loading +bun build --compile --no-compile-autoload-dotenv ./app.ts --outfile myapp + +# Disable bunfig.toml loading +bun build --compile --no-compile-autoload-bunfig ./app.ts --outfile myapp + +# Disable both +bun build --compile --no-compile-autoload-dotenv --no-compile-autoload-bunfig ./app.ts --outfile myapp +``` + +You can also configure this via the JavaScript API: + +```ts +await Bun.build({ + entrypoints: ["./app.ts"], + compile: { + autoloadDotenv: false, // Disable .env loading + autoloadBunfig: false, // Disable bunfig.toml loading + }, +}); +``` + +--- + ## Act as the Bun CLI New in Bun v1.2.16 @@ -259,12 +288,12 @@ console.log(`Server running at http://localhost:${server.port}`);

Hello World

- + ``` -```ts app.js icon="file-code" +```ts app.ts icon="file-code" console.log("Hello from the client!"); ``` @@ -524,12 +553,46 @@ codesign -vvv --verify ./myapp --- +## Code splitting + +Standalone executables support code splitting. Use `--compile` with `--splitting` to create an executable that loads code-split chunks at runtime. + +```bash +bun build --compile --splitting ./src/entry.ts --outdir ./build +``` + + + +```ts src/entry.ts icon="/icons/typescript.svg" +console.log("Entrypoint loaded"); +const lazy = await import("./lazy.ts"); +lazy.hello(); +``` + +```ts src/lazy.ts icon="/icons/typescript.svg" +export function hello() { + console.log("Lazy module loaded"); +} +``` + + + +```bash terminal icon="terminal" +./build/entry +``` + +```txt +Entrypoint loaded +Lazy module loaded +``` + +--- + ## Unsupported CLI arguments Currently, the `--compile` flag can only accept a single entrypoint at a time and does not support the following flags: -- `--outdir` — use `outfile` instead. -- `--splitting` +- `--outdir` — use `outfile` instead (except when using with `--splitting`). - `--public-path` - `--target=node` or `--target=browser` - `--no-bundle` - we always bundle everything into the executable. diff --git a/docs/bundler/fullstack.mdx b/docs/bundler/fullstack.mdx index 937d41d39f..c28241d8ba 100644 --- a/docs/bundler/fullstack.mdx +++ b/docs/bundler/fullstack.mdx @@ -492,6 +492,28 @@ Bun will lazily resolve and load each plugin and use them to bundle your routes. the CLI. +## Inline Environment Variables + +Bun can replace `process.env.*` references in your frontend JavaScript and TypeScript with their actual values at build time. Configure the `env` option in your `bunfig.toml`: + +```toml title="bunfig.toml" icon="settings" +[serve.static] +env = "PUBLIC_*" # only inline env vars starting with PUBLIC_ (recommended) +# env = "inline" # inline all environment variables +# env = "disable" # disable env var replacement (default) +``` + + + This only works with literal `process.env.FOO` references, not `import.meta.env` or indirect access like `const env = + process.env; env.FOO`. + +If an environment variable is not set, you may see runtime errors like `ReferenceError: process + is not defined` in the browser. + + + +See the [HTML & static sites documentation](/bundler/html-static#inline-environment-variables) for more details on build-time configuration and examples. + ## How It Works Bun uses `HTMLRewriter` to scan for `"); --- -See [Docs > API > Utils](https://bun.com/docs/api/utils) for more useful utilities. +See [Docs > API > Utils](/runtime/utils) for more useful utilities. diff --git a/docs/guides/util/file-url-to-path.mdx b/docs/guides/util/file-url-to-path.mdx index 1ff86fc31b..3990f3befb 100644 --- a/docs/guides/util/file-url-to-path.mdx +++ b/docs/guides/util/file-url-to-path.mdx @@ -13,4 +13,4 @@ Bun.fileURLToPath("file:///path/to/file.txt"); --- -See [Docs > API > Utils](https://bun.com/docs/api/utils) for more useful utilities. +See [Docs > API > Utils](/runtime/utils) for more useful utilities. diff --git a/docs/guides/util/gzip.mdx b/docs/guides/util/gzip.mdx index 84b9d97067..0a3763f9ed 100644 --- a/docs/guides/util/gzip.mdx +++ b/docs/guides/util/gzip.mdx @@ -17,4 +17,4 @@ const decompressed = Bun.gunzipSync(compressed); --- -See [Docs > API > Utils](https://bun.com/docs/api/utils) for more useful utilities. +See [Docs > API > Utils](/runtime/utils) for more useful utilities. diff --git a/docs/guides/util/hash-a-password.mdx b/docs/guides/util/hash-a-password.mdx index d45d6da6e2..ef01dde286 100644 --- a/docs/guides/util/hash-a-password.mdx +++ b/docs/guides/util/hash-a-password.mdx @@ -53,4 +53,4 @@ const isMatch = await Bun.password.verify(password, hash); --- -See [Docs > API > Hashing](https://bun.com/docs/api/hashing#bun-password) for complete documentation. +See [Docs > API > Hashing](/runtime/hashing#bun-password) for complete documentation. diff --git a/docs/guides/util/import-meta-dir.mdx b/docs/guides/util/import-meta-dir.mdx index 2890273034..8a2355cd89 100644 --- a/docs/guides/util/import-meta-dir.mdx +++ b/docs/guides/util/import-meta-dir.mdx @@ -4,7 +4,7 @@ sidebarTitle: import.meta.dir mode: center --- -Bun provides a handful of module-specific utilities on the [`import.meta`](https://bun.com/docs/api/import-meta) object. +Bun provides a handful of module-specific utilities on the [`import.meta`](/runtime/module-resolution#import-meta) object. ```ts /a/b/c.ts icon="/icons/typescript.svg" import.meta.dir; // => "/a/b" @@ -12,4 +12,4 @@ import.meta.dir; // => "/a/b" --- -See [Docs > API > import.meta](https://bun.com/docs/api/import-meta) for complete documentation. +See [Docs > API > import.meta](/runtime/module-resolution#import-meta) for complete documentation. diff --git a/docs/guides/util/import-meta-file.mdx b/docs/guides/util/import-meta-file.mdx index cf16226b35..01edbafa66 100644 --- a/docs/guides/util/import-meta-file.mdx +++ b/docs/guides/util/import-meta-file.mdx @@ -4,7 +4,7 @@ sidebarTitle: import.meta.file mode: center --- -Bun provides a handful of module-specific utilities on the [`import.meta`](https://bun.com/docs/api/import-meta) object. Use `import.meta.file` to retrieve the name of the current file. +Bun provides a handful of module-specific utilities on the [`import.meta`](/runtime/module-resolution#import-meta) object. Use `import.meta.file` to retrieve the name of the current file. ```ts /a/b/c.ts icon="/icons/typescript.svg" import.meta.file; // => "c.ts" @@ -12,4 +12,4 @@ import.meta.file; // => "c.ts" --- -See [Docs > API > import.meta](https://bun.com/docs/api/import-meta) for complete documentation. +See [Docs > API > import.meta](/runtime/module-resolution#import-meta) for complete documentation. diff --git a/docs/guides/util/import-meta-path.mdx b/docs/guides/util/import-meta-path.mdx index 3e1f20aec8..80e92bfd1f 100644 --- a/docs/guides/util/import-meta-path.mdx +++ b/docs/guides/util/import-meta-path.mdx @@ -4,7 +4,7 @@ sidebarTitle: import.meta.path mode: center --- -Bun provides a handful of module-specific utilities on the [`import.meta`](https://bun.com/docs/api/import-meta) object. Use `import.meta.path` to retrieve the absolute path of the current file. +Bun provides a handful of module-specific utilities on the [`import.meta`](/runtime/module-resolution#import-meta) object. Use `import.meta.path` to retrieve the absolute path of the current file. ```ts /a/b/c.ts icon="/icons/typescript.svg" import.meta.path; // => "/a/b/c.ts" @@ -12,4 +12,4 @@ import.meta.path; // => "/a/b/c.ts" --- -See [Docs > API > import.meta](https://bun.com/docs/api/import-meta) for complete documentation. +See [Docs > API > import.meta](/runtime/module-resolution#import-meta) for complete documentation. diff --git a/docs/guides/util/javascript-uuid.mdx b/docs/guides/util/javascript-uuid.mdx index 1d9a0ea0f6..1c0d4bfa6b 100644 --- a/docs/guides/util/javascript-uuid.mdx +++ b/docs/guides/util/javascript-uuid.mdx @@ -8,7 +8,7 @@ Use `crypto.randomUUID()` to generate a UUID v4. This API works in Bun, Node.js, ```ts crypto.randomUUID(); -// => "123e4567-e89b-12d3-a456-426614174000" +// => "123e4567-e89b-42d3-a456-426614174000" ``` --- @@ -22,4 +22,4 @@ Bun.randomUUIDv7(); --- -See [Docs > API > Utils](https://bun.com/docs/api/utils) for more useful utilities. +See [Docs > API > Utils](/runtime/utils) for more useful utilities. diff --git a/docs/guides/util/main.mdx b/docs/guides/util/main.mdx index f308c64a7c..ea41dbf2d1 100644 --- a/docs/guides/util/main.mdx +++ b/docs/guides/util/main.mdx @@ -40,4 +40,4 @@ bun run foo.ts --- -See [Docs > API > Utils](https://bun.com/docs/api/utils) for more useful utilities. +See [Docs > API > Utils](/runtime/utils) for more useful utilities. diff --git a/docs/guides/util/path-to-file-url.mdx b/docs/guides/util/path-to-file-url.mdx index aac29788df..65ffe7b201 100644 --- a/docs/guides/util/path-to-file-url.mdx +++ b/docs/guides/util/path-to-file-url.mdx @@ -13,4 +13,4 @@ Bun.pathToFileURL("/path/to/file.txt"); --- -See [Docs > API > Utils](https://bun.com/docs/api/utils) for more useful utilities. +See [Docs > API > Utils](/runtime/utils) for more useful utilities. diff --git a/docs/guides/util/sleep.mdx b/docs/guides/util/sleep.mdx index 30daedc805..738738c213 100644 --- a/docs/guides/util/sleep.mdx +++ b/docs/guides/util/sleep.mdx @@ -21,4 +21,4 @@ await new Promise(resolve => setTimeout(resolve, ms)); --- -See [Docs > API > Utils](https://bun.com/docs/api/utils) for more useful utilities. +See [Docs > API > Utils](/runtime/utils) for more useful utilities. diff --git a/docs/guides/util/upgrade.mdx b/docs/guides/util/upgrade.mdx new file mode 100644 index 0000000000..dea2faacd1 --- /dev/null +++ b/docs/guides/util/upgrade.mdx @@ -0,0 +1,93 @@ +--- +title: Upgrade Bun to the latest version +sidebarTitle: Upgrade Bun +mode: center +--- + +Bun can upgrade itself using the built-in `bun upgrade` command. This is the fastest way to get the latest features and bug fixes. + +```bash terminal icon="terminal" +bun upgrade +``` + +This downloads and installs the latest stable version of Bun, replacing the currently installed version. + +To see the current version of Bun, run `bun --version`. + +--- + +## Verify the upgrade + +After upgrading, verify the new version: + +```bash terminal icon="terminal" +bun --version +# Output: 1.x.y + +# See the exact commit of the Bun binary +bun --revision +# Output: 1.x.y+abc123def +``` + +--- + +## Upgrade to canary builds + +Canary builds are automatically released on every commit to the `main` branch. These are untested but useful for trying new features or verifying bug fixes before they're released. + +```bash terminal icon="terminal" +bun upgrade --canary +``` + +Canary builds are not recommended for production use. They may contain bugs or breaking changes. + +--- + +## Switch back to stable + +If you're on a canary build and want to return to the latest stable release: + +```bash terminal icon="terminal" +bun upgrade --stable +``` + +--- + +## Install a specific version + +To install a specific version of Bun, use the install script with a version tag: + + + + ```bash terminal icon="terminal" + curl -fsSL https://bun.sh/install | bash -s "bun-v1.3.3" + ``` + + + ```powershell PowerShell icon="windows" + iex "& {$(irm https://bun.sh/install.ps1)} -Version 1.3.3" + ``` + + + +--- + +## Package manager users + +If you installed Bun via a package manager, use that package manager to upgrade instead of `bun upgrade` to avoid conflicts. + + +**Homebrew users**
+To avoid conflicts with Homebrew, use `brew upgrade bun` instead. + +**Scoop users**
+To avoid conflicts with Scoop, use `scoop update bun` instead. + +
+ +--- + +## See also + +- [Installation](/installation) — Install Bun for the first time +- [Update packages](/pm/cli/update) — Update dependencies to latest versions diff --git a/docs/guides/util/version.mdx b/docs/guides/util/version.mdx index 73b3942744..6348fbf9e5 100644 --- a/docs/guides/util/version.mdx +++ b/docs/guides/util/version.mdx @@ -7,7 +7,7 @@ mode: center Get the current version of Bun in a semver format. ```ts index.ts icon="/icons/typescript.svg" -Bun.version; // => "1.3.2" +Bun.version; // => "1.3.3" ``` --- @@ -20,4 +20,4 @@ Bun.revision; // => "49231b2cb9aa48497ab966fc0bb6b742dacc4994" --- -See [Docs > API > Utils](https://bun.com/docs/api/utils) for more useful utilities. +See [Docs > API > Utils](/runtime/utils) for more useful utilities. diff --git a/docs/guides/util/which-path-to-executable-bin.mdx b/docs/guides/util/which-path-to-executable-bin.mdx index fe9cda53a6..e524561089 100644 --- a/docs/guides/util/which-path-to-executable-bin.mdx +++ b/docs/guides/util/which-path-to-executable-bin.mdx @@ -14,4 +14,4 @@ Bun.which("bun"); // => "/home/user/.bun/bin/bun" --- -See [Docs > API > Utils](https://bun.com/docs/api/utils#bun-which) for complete documentation. +See [Docs > API > Utils](/runtime/utils#bun-which) for complete documentation. diff --git a/docs/guides/websocket/context.mdx b/docs/guides/websocket/context.mdx index d313de2605..3104ec9a12 100644 --- a/docs/guides/websocket/context.mdx +++ b/docs/guides/websocket/context.mdx @@ -6,10 +6,10 @@ mode: center When building a WebSocket server, it's typically necessary to store some identifying information or context associated with each connected client. -With [Bun.serve()](https://bun.com/docs/api/websockets contextual-data), this "contextual data" is set when the connection is initially upgraded by passing a `data` parameter in the `server.upgrade()` call. +With [Bun.serve()](/runtime/http/websockets#contextual-data), this "contextual data" is set when the connection is initially upgraded by passing a `data` parameter in the `server.upgrade()` call. ```ts server.ts icon="/icons/typescript.svg" -Bun.serve<{ socketId: number }>({ +Bun.serve({ fetch(req, server) { const success = server.upgrade(req, { data: { @@ -22,6 +22,9 @@ Bun.serve<{ socketId: number }>({ // ... }, websocket: { + // TypeScript: specify the type of ws.data like this + data: {} as { socketId: number }, + // define websocket handlers async message(ws, message) { // the contextual data is available as the `data` property @@ -43,8 +46,7 @@ type WebSocketData = { userId: string; }; -// TypeScript: specify the type of `data` -Bun.serve({ +Bun.serve({ async fetch(req, server) { // use a library to parse cookies const cookies = parseCookies(req.headers.get("Cookie")); @@ -62,6 +64,9 @@ Bun.serve({ if (upgraded) return undefined; }, websocket: { + // TypeScript: specify the type of ws.data like this + data: {} as WebSocketData, + async message(ws, message) { // save the message to a database await saveMessageToDatabase({ diff --git a/docs/guides/websocket/pubsub.mdx b/docs/guides/websocket/pubsub.mdx index b70c094046..056d37b838 100644 --- a/docs/guides/websocket/pubsub.mdx +++ b/docs/guides/websocket/pubsub.mdx @@ -9,7 +9,7 @@ Bun's server-side `WebSocket` API provides a native pub-sub API. Sockets can be This code snippet implements a simple single-channel chat server. ```ts server.ts icon="/icons/typescript.svg" -const server = Bun.serve<{ username: string }>({ +const server = Bun.serve({ fetch(req, server) { const cookies = req.headers.get("cookie"); const username = getUsernameFromCookies(cookies); @@ -19,6 +19,9 @@ const server = Bun.serve<{ username: string }>({ return new Response("Hello world"); }, websocket: { + // TypeScript: specify the type of ws.data like this + data: {} as { username: string }, + open(ws) { const msg = `${ws.data.username} has entered the chat`; ws.subscribe("the-group-chat"); diff --git a/docs/guides/websocket/simple.mdx b/docs/guides/websocket/simple.mdx index 1a2dd2dc15..6239d13365 100644 --- a/docs/guides/websocket/simple.mdx +++ b/docs/guides/websocket/simple.mdx @@ -4,12 +4,12 @@ sidebarTitle: Simple server mode: center --- -Start a simple WebSocket server using [`Bun.serve`](https://bun.com/docs/api/http). +Start a simple WebSocket server using [`Bun.serve`](/runtime/http/server). Inside `fetch`, we attempt to upgrade incoming `ws:` or `wss:` requests to WebSocket connections. ```ts server.ts icon="/icons/typescript.svg" -const server = Bun.serve<{ authToken: string }>({ +const server = Bun.serve({ fetch(req, server) { const success = server.upgrade(req); if (success) { @@ -22,6 +22,9 @@ const server = Bun.serve<{ authToken: string }>({ return new Response("Hello world!"); }, websocket: { + // TypeScript: specify the type of ws.data like this + data: {} as { authToken: string }, + // this is called when a message is received async message(ws, message) { console.log(`Received ${message}`); diff --git a/docs/guides/write-file/basic.mdx b/docs/guides/write-file/basic.mdx index 4edd4207a2..6f3eec5287 100644 --- a/docs/guides/write-file/basic.mdx +++ b/docs/guides/write-file/basic.mdx @@ -6,7 +6,7 @@ mode: center This code snippet writes a string to disk at a particular _absolute path_. -It uses the fast [`Bun.write()`](https://bun.com/docs/api/file-io#writing-files-bun-write) API to efficiently write data to disk. The first argument is a _destination_; the second is the _data_ to write. +It uses the fast [`Bun.write()`](/runtime/file-io#writing-files-bun-write) API to efficiently write data to disk. The first argument is a _destination_; the second is the _data_ to write. ```ts const path = "/path/to/file.txt"; @@ -43,4 +43,4 @@ const bytes = await Bun.write(path, "Lorem ipsum"); --- -See [Docs > API > File I/O](https://bun.com/docs/api/file-io#writing-files-bun-write) for complete documentation of `Bun.write()`. +See [Docs > API > File I/O](/runtime/file-io#writing-files-bun-write) for complete documentation of `Bun.write()`. diff --git a/docs/guides/write-file/blob.mdx b/docs/guides/write-file/blob.mdx index ccaaaefc78..78810b740d 100644 --- a/docs/guides/write-file/blob.mdx +++ b/docs/guides/write-file/blob.mdx @@ -6,7 +6,7 @@ mode: center This code snippet writes a `Blob` to disk at a particular path. -It uses the fast [`Bun.write()`](https://bun.com/docs/api/file-io#writing-files-bun-write) API to efficiently write data to disk. The first argument is a _destination_, like an absolute path or `BunFile` instance. The second argument is the _data_ to write. +It uses the fast [`Bun.write()`](/runtime/file-io#writing-files-bun-write) API to efficiently write data to disk. The first argument is a _destination_, like an absolute path or `BunFile` instance. The second argument is the _data_ to write. ```ts const path = "/path/to/file.txt"; @@ -27,4 +27,4 @@ await Bun.write(path, data); --- -See [Docs > API > File I/O](https://bun.com/docs/api/file-io#writing-files-bun-write) for complete documentation of `Bun.write()`. +See [Docs > API > File I/O](/runtime/file-io#writing-files-bun-write) for complete documentation of `Bun.write()`. diff --git a/docs/guides/write-file/cat.mdx b/docs/guides/write-file/cat.mdx index 44b5d91cf0..92ca362e04 100644 --- a/docs/guides/write-file/cat.mdx +++ b/docs/guides/write-file/cat.mdx @@ -4,7 +4,7 @@ sidebarTitle: Write file to stdout mode: center --- -Bun exposes `stdout` as a `BunFile` with the `Bun.stdout` property. This can be used as a destination for [`Bun.write()`](https://bun.com/docs/api/file-io#writing-files-bun-write). +Bun exposes `stdout` as a `BunFile` with the `Bun.stdout` property. This can be used as a destination for [`Bun.write()`](/runtime/file-io#writing-files-bun-write). This code writes a file to `stdout` similar to the `cat` command in Unix. @@ -16,4 +16,4 @@ await Bun.write(Bun.stdout, file); --- -See [Docs > API > File I/O](https://bun.com/docs/api/file-io#writing-files-bun-write) for complete documentation of `Bun.write()`. +See [Docs > API > File I/O](/runtime/file-io#writing-files-bun-write) for complete documentation of `Bun.write()`. diff --git a/docs/guides/write-file/file-cp.mdx b/docs/guides/write-file/file-cp.mdx index d43d5f7225..d8eb08d67c 100644 --- a/docs/guides/write-file/file-cp.mdx +++ b/docs/guides/write-file/file-cp.mdx @@ -6,7 +6,7 @@ mode: center This code snippet copies a file to another location on disk. -It uses the fast [`Bun.write()`](https://bun.com/docs/api/file-io#writing-files-bun-write) API to efficiently write data to disk. The first argument is a _destination_, like an absolute path or `BunFile` instance. The second argument is the _data_ to write. +It uses the fast [`Bun.write()`](/runtime/file-io#writing-files-bun-write) API to efficiently write data to disk. The first argument is a _destination_, like an absolute path or `BunFile` instance. The second argument is the _data_ to write. ```ts const file = Bun.file("/path/to/original.txt"); @@ -15,4 +15,4 @@ await Bun.write("/path/to/copy.txt", file); --- -See [Docs > API > File I/O](https://bun.com/docs/api/file-io#writing-files-bun-write) for complete documentation of `Bun.write()`. +See [Docs > API > File I/O](/runtime/file-io#writing-files-bun-write) for complete documentation of `Bun.write()`. diff --git a/docs/guides/write-file/filesink.mdx b/docs/guides/write-file/filesink.mdx index 5414ed933f..68333e5445 100644 --- a/docs/guides/write-file/filesink.mdx +++ b/docs/guides/write-file/filesink.mdx @@ -51,4 +51,4 @@ writer.end(); --- -Full documentation: [FileSink](https://bun.com/docs/api/file-io#incremental-writing-with-filesink). +Full documentation: [FileSink](/runtime/file-io#incremental-writing-with-filesink). diff --git a/docs/guides/write-file/response.mdx b/docs/guides/write-file/response.mdx index 2f0721623a..20e04ff69c 100644 --- a/docs/guides/write-file/response.mdx +++ b/docs/guides/write-file/response.mdx @@ -6,7 +6,7 @@ mode: center This code snippet writes a `Response` to disk at a particular path. Bun will consume the `Response` body according to its `Content-Type` header. -It uses the fast [`Bun.write()`](https://bun.com/docs/api/file-io#writing-files-bun-write) API to efficiently write data to disk. The first argument is a _destination_, like an absolute path or `BunFile` instance. The second argument is the _data_ to write. +It uses the fast [`Bun.write()`](/runtime/file-io#writing-files-bun-write) API to efficiently write data to disk. The first argument is a _destination_, like an absolute path or `BunFile` instance. The second argument is the _data_ to write. ```ts const result = await fetch("https://bun.com"); @@ -16,4 +16,4 @@ await Bun.write(path, result); --- -See [Docs > API > File I/O](https://bun.com/docs/api/file-io#writing-files-bun-write) for complete documentation of `Bun.write()`. +See [Docs > API > File I/O](/runtime/file-io#writing-files-bun-write) for complete documentation of `Bun.write()`. diff --git a/docs/guides/write-file/stdout.mdx b/docs/guides/write-file/stdout.mdx index 1e980c0947..3c1d9fd681 100644 --- a/docs/guides/write-file/stdout.mdx +++ b/docs/guides/write-file/stdout.mdx @@ -12,7 +12,7 @@ console.log("Lorem ipsum"); --- -For more advanced use cases, Bun exposes `stdout` as a `BunFile` via the `Bun.stdout` property. This can be used as a destination for [`Bun.write()`](https://bun.com/docs/api/file-io#writing-files-bun-write). +For more advanced use cases, Bun exposes `stdout` as a `BunFile` via the `Bun.stdout` property. This can be used as a destination for [`Bun.write()`](/runtime/file-io#writing-files-bun-write). ```ts await Bun.write(Bun.stdout, "Lorem ipsum"); @@ -20,4 +20,4 @@ await Bun.write(Bun.stdout, "Lorem ipsum"); --- -See [Docs > API > File I/O](https://bun.com/docs/api/file-io#writing-files-bun-write) for complete documentation of `Bun.write()`. +See [Docs > API > File I/O](/runtime/file-io#writing-files-bun-write) for complete documentation of `Bun.write()`. diff --git a/docs/guides/write-file/stream.mdx b/docs/guides/write-file/stream.mdx index 739c60c320..1c13bd5c48 100644 --- a/docs/guides/write-file/stream.mdx +++ b/docs/guides/write-file/stream.mdx @@ -4,7 +4,7 @@ sidebarTitle: Write stream mode: center --- -To write a `ReadableStream` to disk, first create a `Response` instance from the stream. This `Response` can then be written to disk using [`Bun.write()`](https://bun.com/docs/api/file-io#writing-files-bun-write). +To write a `ReadableStream` to disk, first create a `Response` instance from the stream. This `Response` can then be written to disk using [`Bun.write()`](/runtime/file-io#writing-files-bun-write). ```ts const stream: ReadableStream = ...; @@ -16,4 +16,4 @@ await Bun.write(path, response); --- -See [Docs > API > File I/O](https://bun.com/docs/api/file-io#writing-files-bun-write) for complete documentation of `Bun.write()`. +See [Docs > API > File I/O](/runtime/file-io#writing-files-bun-write) for complete documentation of `Bun.write()`. diff --git a/docs/guides/write-file/unlink.mdx b/docs/guides/write-file/unlink.mdx index d20cc37287..7835f503d2 100644 --- a/docs/guides/write-file/unlink.mdx +++ b/docs/guides/write-file/unlink.mdx @@ -15,4 +15,4 @@ await file.delete(); --- -See [Docs > API > File I/O](https://bun.com/docs/api/file-io#reading-files-bun-file) for complete documentation of `Bun.file()`. +See [Docs > API > File I/O](/runtime/file-io#reading-files-bun-file) for complete documentation of `Bun.file()`. diff --git a/docs/images/templates/bun-nextjs-basic.png b/docs/images/templates/bun-nextjs-basic.png new file mode 100644 index 0000000000..95a1c90370 Binary files /dev/null and b/docs/images/templates/bun-nextjs-basic.png differ diff --git a/docs/images/templates/bun-nextjs-todo.png b/docs/images/templates/bun-nextjs-todo.png new file mode 100644 index 0000000000..4a2d21eded Binary files /dev/null and b/docs/images/templates/bun-nextjs-todo.png differ diff --git a/docs/images/templates/bun-tanstack-basic.png b/docs/images/templates/bun-tanstack-basic.png new file mode 100644 index 0000000000..448e499e88 Binary files /dev/null and b/docs/images/templates/bun-tanstack-basic.png differ diff --git a/docs/images/templates/bun-tanstack-start.png b/docs/images/templates/bun-tanstack-start.png new file mode 100644 index 0000000000..a2c4c5f327 Binary files /dev/null and b/docs/images/templates/bun-tanstack-start.png differ diff --git a/docs/images/templates/bun-tanstack-todo.png b/docs/images/templates/bun-tanstack-todo.png new file mode 100644 index 0000000000..9701e86520 Binary files /dev/null and b/docs/images/templates/bun-tanstack-todo.png differ diff --git a/docs/index.mdx b/docs/index.mdx index f45293b998..471e021af4 100644 --- a/docs/index.mdx +++ b/docs/index.mdx @@ -127,7 +127,7 @@ Bun is designed from the ground-up with today's JavaScript ecosystem in mind. - **Speed**. Bun processes start [4x faster than Node.js](https://twitter.com/jarredsumner/status/1499225725492076544) 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`](https://developer.mozilla.org/en-US/Web/API/Headers) and [`URL`](https://developer.mozilla.org/en-US/Web/API/URL) directly use [Safari's implementation](https://github.com/oven-sh/bun/blob/HEAD/src/bun.js/bindings/webcore/JSFetchHeaders.cpp). +- **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`](https://developer.mozilla.org/en-US/docs/Web/API/Headers) and [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL) directly use [Safari's implementation](https://github.com/oven-sh/bun/blob/HEAD/src/bun.js/bindings/webcore/JSFetchHeaders.cpp). - **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](/runtime/nodejs-compat) 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. diff --git a/docs/installation.mdx b/docs/installation.mdx index 4f518c3033..99f117bcd6 100644 --- a/docs/installation.mdx +++ b/docs/installation.mdx @@ -1,6 +1,6 @@ --- title: Installation -description: Install Bun +description: Install Bun with npm, Homebrew, Docker, or the official script. --- ## Overview @@ -209,7 +209,7 @@ Since Bun is a single binary, you can install older versions by re-running the i To install a specific version, pass the git tag to the install script: ```bash terminal icon="terminal" - curl -fsSL https://bun.com/install | bash -s "bun-v1.3.2" + curl -fsSL https://bun.com/install | bash -s "bun-v1.3.3" ``` @@ -217,7 +217,7 @@ Since Bun is a single binary, you can install older versions by re-running the i On Windows, pass the version number to the PowerShell install script: ```powershell PowerShell icon="windows" - iex "& {$(irm https://bun.com/install.ps1)} -Version 1.3.2" + iex "& {$(irm https://bun.com/install.ps1)} -Version 1.3.3" ``` diff --git a/docs/normalize-internal-links.js b/docs/normalize-internal-links.js index 3fd5d44504..97a1957b4d 100644 --- a/docs/normalize-internal-links.js +++ b/docs/normalize-internal-links.js @@ -15,7 +15,6 @@ if (element.getAttribute("rel") === "noreferrer") { element.removeAttribute("rel"); } - console.log(`Removed target="_blank" from: ${element.textContent || element.innerHTML.substring(0, 50)}`); } }); }); diff --git a/docs/pm/bunx.mdx b/docs/pm/bunx.mdx index d2299cf9df..b92ef339ad 100644 --- a/docs/pm/bunx.mdx +++ b/docs/pm/bunx.mdx @@ -3,6 +3,8 @@ title: "bunx" description: "Run packages from npm" --- +import Bunx from "/snippets/cli/bunx.mdx"; + `bunx` is an alias for `bun x`. The `bunx` CLI will be auto-installed when you install `bun`. Use `bunx` to auto-install and run packages from `npm`. It's Bun's equivalent of `npx` or `yarn dlx`. @@ -30,7 +32,7 @@ Packages can declare executables in the `"bin"` field of their `package.json`. T These executables are commonly plain JavaScript files marked with a [shebang line]() to indicate which program should be used to execute them. The following file indicates that it should be executed with `node`. -```ts dist/index.js icon="/icons/javascript.svg" +```js dist/index.js icon="/icons/javascript.svg" #!/usr/bin/env node console.log("Hello world!"); @@ -52,6 +54,8 @@ To pass additional command-line flags and arguments through to the executable, p bunx my-cli --foo bar ``` +--- + ## Shebangs By default, Bun respects shebangs. If an executable is marked with `#!/usr/bin/env node`, Bun will spin up a `node` process to execute the file. However, in some cases it may be desirable to run executables using Bun's runtime, even if the executable indicates otherwise. To do so, include the `--bun` flag. @@ -78,6 +82,10 @@ bunx --package @angular/cli ng To force bun to always be used with a script, use a shebang. -```ts dist/index.js icon="/icons/javascript.svg" +```js dist/index.js icon="/icons/javascript.svg" #!/usr/bin/env bun ``` + +--- + + diff --git a/docs/pm/cli/info.mdx b/docs/pm/cli/info.mdx new file mode 100644 index 0000000000..9e4feb1352 --- /dev/null +++ b/docs/pm/cli/info.mdx @@ -0,0 +1,70 @@ +--- +title: "bun info" +description: "Display package metadata from the npm registry" +--- + +`bun info` displays package metadata from the npm registry. + +## Usage + +```bash terminal icon="terminal" +bun info react +``` + +This will display information about the `react` package, including its latest version, description, homepage, dependencies, and more. + +## Viewing specific versions + +To view information about a specific version: + +```bash terminal icon="terminal" +bun info react@18.0.0 +``` + +## Viewing specific properties + +You can also query specific properties from the package metadata: + +```bash terminal icon="terminal" +bun info react version +bun info react dependencies +bun info react repository.url +``` + +## JSON output + +To get the output in JSON format, use the `--json` flag: + +```bash terminal icon="terminal" +bun info react --json +``` + +## Alias + +`bun pm view` is an alias for `bun info`: + +```bash terminal icon="terminal" +bun pm view react # equivalent to: bun info react +``` + +## Examples + +```bash terminal icon="terminal" +# View basic package information +bun info is-number + +# View a specific version +bun info is-number@7.0.0 + +# View all available versions +bun info is-number versions + +# View package dependencies +bun info express dependencies + +# View package homepage +bun info lodash homepage + +# Get JSON output +bun info react --json +``` diff --git a/docs/pm/cli/install.mdx b/docs/pm/cli/install.mdx index e5cfa58836..054e364a91 100644 --- a/docs/pm/cli/install.mdx +++ b/docs/pm/cli/install.mdx @@ -134,14 +134,14 @@ For more information on filtering with `bun install`, refer to [Package Manager 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. Refer to [Package manager > Overrides and resolutions](/pm/overrides) for complete documentation. -```json package.json file="file-json" +{/* prettier-ignore */} +```json package.json icon="file-json" { "name": "my-app", "dependencies": { "foo": "^2.0.0" }, - "overrides": { - // [!code ++] + "overrides": { // [!code ++] "bar": "~4.4.0" // [!code ++] } // [!code ++] } @@ -304,7 +304,16 @@ For more advanced security scanning, including integration with services & custo ## Configuration -The default behavior of `bun install` can be configured in `bunfig.toml`. The default values are shown below. +### 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. The default behavior of `bun install` can be configured in `bunfig.toml`. The default values are shown below. ```toml bunfig.toml icon="settings" [install] @@ -345,7 +354,29 @@ minimumReleaseAge = 259200 # seconds minimumReleaseAgeExcludes = ["@types/node", "typescript"] ``` ---- +### Configuring with environment variables + +Environment variables have a higher priority than `bunfig.toml`. + +| Name | Description | +| ---------------------------------- | ------------------------------------------------------------- | +| `BUN_CONFIG_REGISTRY` | Set an npm registry (default: https://registry.npmjs.org) | +| `BUN_CONFIG_TOKEN` | Set an auth token (currently does nothing) | +| `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.lock` doesn’t exist or `package.json` has changed dependencies, tarballs are downloaded & extracted eagerly while resolving. + +When a `bun.lock` 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. ## CI/CD @@ -395,6 +426,94 @@ jobs: run: bun run build ``` +## 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. + +### `--cpu` and `--os` flags + +You can override the target platform for package selection: + +```bash +bun install --cpu=x64 --os=linux +``` + +This installs packages for the specified platform instead of the current system. Useful for cross-platform builds or when preparing deployments for different environments. + +**Accepted values for `--cpu`**: `arm64`, `x64`, `ia32`, `ppc64`, `s390x` + +**Accepted values for `--os`**: `linux`, `darwin`, `win32`, `freebsd`, `openbsd`, `sunos`, `aix` + +## Peer dependencies? + +Peer dependencies are handled similarly to yarn. `bun install` will automatically install peer dependencies. If the dependency is marked optional in `peerDependenciesMeta`, an existing dependency will be chosen if possible. + +## Lockfile + +`bun.lock` is Bun’s lockfile format. See [our blogpost about the text lockfile](https://bun.com/blog/bun-lock-text-lockfile). + +Prior to Bun 1.2, the lockfile was binary and called `bun.lockb`. Old lockfiles can be upgraded to the new format by running `bun install --save-text-lockfile --frozen-lockfile --lockfile-only`, and then deleting `bun.lockb`. + +## Cache + +To delete the cache: + +```bash +bun pm cache rm +# or +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` or `bun`. See [Node.js documentation on `--preserve-symlinks`](https://nodejs.org/api/cli.html#--preserve-symlinks). + +```bash +rm -rf node_modules +bun install --backend symlink +bun --preserve-symlinks ./my-file.js +node --preserve-symlinks ./my-file.js # https://nodejs.org/api/cli.html#--preserve-symlinks +``` + +## 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. + ## pnpm migration 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. diff --git a/docs/pm/cli/link.mdx b/docs/pm/cli/link.mdx index 6515ae30eb..b0b46314aa 100644 --- a/docs/pm/cli/link.mdx +++ b/docs/pm/cli/link.mdx @@ -14,7 +14,7 @@ bun link ``` ```txt -bun link v1.x (7416672e) +bun link v1.3.3 (7416672e) Success! Registered "cool-pkg" To use cool-pkg in a project, run: @@ -43,6 +43,19 @@ In addition, the `--save` flag can be used to add `cool-pkg` to the `dependencie } ``` +## Unlinking + +Use `bun unlink` in the root directory to unregister a local package. + +```bash terminal icon="terminal" +cd /path/to/cool-pkg +bun unlink +``` + +```txt +bun unlink v1.3.3 (7416672e) +``` + --- diff --git a/docs/pm/cli/outdated.mdx b/docs/pm/cli/outdated.mdx index da72e0c490..bf62b03a06 100644 --- a/docs/pm/cli/outdated.mdx +++ b/docs/pm/cli/outdated.mdx @@ -15,7 +15,7 @@ bun outdated | Package | Current | Update | Latest | | ------------------------------ | ------- | --------- | ---------- | | @sinclair/typebox | 0.34.15 | 0.34.16 | 0.34.16 | -| @types/bun (dev) | 1.2.0 | 1.2.23 | 1.2.23 | +| @types/bun (dev) | 1.3.0 | 1.3.3 | 1.3.3 | | eslint (dev) | 8.57.1 | 8.57.1 | 9.20.0 | | eslint-plugin-security (dev) | 2.1.1 | 2.1.1 | 3.0.1 | | eslint-plugin-sonarjs (dev) | 0.23.0 | 0.23.0 | 3.0.1 | @@ -55,7 +55,7 @@ bun outdated eslint-plugin-security eslint-plugin-sonarjs You can also pass glob patterns to check for outdated packages: ```sh terminal icon="terminal" -bun outdated eslint* +bun outdated 'eslint*' ``` ```txt @@ -75,7 +75,7 @@ bun outdated '@types/*' ```txt | Package | Current | Update | Latest | | ------------------ | ------- | ------ | ------ | -| @types/bun (dev) | 1.2.0 | 1.2.23 | 1.2.23 | +| @types/bun (dev) | 1.3.0 | 1.3.3 | 1.3.3 | ``` Or to exclude all `@types/*` packages: diff --git a/docs/pm/cli/pm.mdx b/docs/pm/cli/pm.mdx index d2f1cca971..01b41ebcdd 100644 --- a/docs/pm/cli/pm.mdx +++ b/docs/pm/cli/pm.mdx @@ -248,7 +248,7 @@ bun pm version ``` ```txt -bun pm version v1.3.2 (ca7428e9) +bun pm version v1.3.3 (ca7428e9) Current package version: v1.0.0 Increment: diff --git a/docs/pm/cli/publish.mdx b/docs/pm/cli/publish.mdx index af65bdfd96..c316b22dd4 100644 --- a/docs/pm/cli/publish.mdx +++ b/docs/pm/cli/publish.mdx @@ -13,7 +13,7 @@ bun publish ``` ```txt -bun publish v1.3.2 (ca7428e9) +bun publish v1.3.3 (ca7428e9) packed 203B package.json packed 224B README.md @@ -89,6 +89,14 @@ The `--dry-run` flag can be used to simulate the publish process without actuall bun publish --dry-run ``` +### `--tolerate-republish` + +Exit with code 0 instead of 1 if the package version already exists. Useful in CI/CD where jobs may be re-run. + +```sh terminal icon="terminal" +bun publish --tolerate-republish +``` + ### `--gzip-level` 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`). diff --git a/docs/pm/overrides.mdx b/docs/pm/overrides.mdx index a8e4f32083..cd7a89d5a5 100644 --- a/docs/pm/overrides.mdx +++ b/docs/pm/overrides.mdx @@ -5,14 +5,14 @@ description: "Control metadependency versions with npm overrides and Yarn resolu 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. +{/* prettier-ignore */} ```json package.json icon="file-json" { "name": "my-app", "dependencies": { "foo": "^2.0.0" }, - "overrides": { - // [!code ++] + "overrides": { // [!code ++] "bar": "~4.4.0" // [!code ++] } // [!code ++] } @@ -50,14 +50,14 @@ Add `bar` to the `"overrides"` field in `package.json`. Bun will defer to the sp overrides](https://docs.npmjs.com/cli/v9/configuring-npm/package-json#overrides) are not supported. +{/* prettier-ignore */} ```json package.json icon="file-json" { "name": "my-app", "dependencies": { "foo": "^2.0.0" }, - "overrides": { - // [!code ++] + "overrides": { // [!code ++] "bar": "~4.4.0" // [!code ++] } // [!code ++] } @@ -69,14 +69,14 @@ The syntax is similar for `"resolutions"`, which is Yarn's alternative to `"over As with `"overrides"`, _nested resolutions_ are not currently supported. +{/* prettier-ignore */} ```json package.json icon="file-json" { "name": "my-app", "dependencies": { "foo": "^2.0.0" }, - "resolutions": { - // [!code ++] + "resolutions": { // [!code ++] "bar": "~4.4.0" // [!code ++] } // [!code ++] } diff --git a/docs/pm/workspaces.mdx b/docs/pm/workspaces.mdx index 6570597dd4..961037914a 100644 --- a/docs/pm/workspaces.mdx +++ b/docs/pm/workspaces.mdx @@ -30,7 +30,7 @@ It's common for a monorepo to have the following structure: 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`. -```json +```json package.json icon="file-json" { "name": "my-project", "version": "1.0.0", @@ -42,14 +42,21 @@ In the root `package.json`, the `"workspaces"` key is used to indicate which sub ``` - **Glob support** — Bun supports full glob syntax in `"workspaces"` (see [here](/runtime/glob#supported-glob-patterns) - for a comprehensive list of supported syntax), _except_ for exclusions (e.g. `!**/excluded/**`), which are not - implemented yet. + **Glob support** — Bun supports full glob syntax in `"workspaces"`, including negative patterns (e.g. + `!**/excluded/**`). See [here](/runtime/glob#supported-glob-patterns) for a comprehensive list of supported syntax. +```json package.json icon="file-json" +{ + "name": "my-project", + "version": "1.0.0", + "workspaces": ["packages/**", "!packages/**/test/**", "!packages/**/template/**"] +} +``` + 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`. -```json +```json packages/pkg-a/package.json icon="file-json" { "name": "pkg-a", "version": "1.0.0", diff --git a/docs/project/building-windows.mdx b/docs/project/building-windows.mdx index 59cb8f788e..9a4a3ab2d7 100644 --- a/docs/project/building-windows.mdx +++ b/docs/project/building-windows.mdx @@ -22,7 +22,7 @@ By default, running unverified scripts are blocked. Bun v1.1 or later. We use Bun to run it's own code generators. ```ps1 -> irm bun.com/install.ps1 | iex +> irm bun.sh/install.ps1 | iex ``` [Visual Studio](https://visualstudio.microsoft.com) with the "Desktop Development with C++" workload. While installing, make sure to install Git as well, if Git for Windows is not already installed. diff --git a/docs/project/contributing.mdx b/docs/project/contributing.mdx index 31a0c511bc..b645b005f1 100644 --- a/docs/project/contributing.mdx +++ b/docs/project/contributing.mdx @@ -7,26 +7,40 @@ Configuring a development environment for Bun can take 10-30 minutes depending o If you are using Windows, please refer to [this guide](/project/building-windows) -## Install Dependencies +## Using Nix (Alternative) + +A Nix flake is provided as an alternative to manual dependency installation: + +```bash +nix develop +# or explicitly use the pure shell +# nix develop .#pure +export CMAKE_SYSTEM_PROCESSOR=$(uname -m) +bun bd +``` + +This provides all dependencies in an isolated, reproducible environment without requiring sudo. + +## Install Dependencies (Manual) Using your system's package manager, install Bun's dependencies: ```bash macOS (Homebrew) -$ brew install automake ccache cmake coreutils gnu-sed go icu4c libiconv libtool ninja pkg-config rust ruby +$ brew install automake cmake coreutils gnu-sed go icu4c libiconv libtool ninja pkg-config rust ruby sccache ``` ```bash Ubuntu/Debian -$ sudo apt install curl wget lsb-release software-properties-common cargo ccache cmake git golang libtool ninja-build pkg-config rustc ruby-full xz-utils +$ sudo apt install curl wget lsb-release software-properties-common cargo cmake git golang libtool ninja-build pkg-config rustc ruby-full xz-utils ``` ```bash Arch -$ sudo pacman -S base-devel ccache cmake git go libiconv libtool make ninja pkg-config python rust sed unzip ruby +$ sudo pacman -S base-devel cmake git go libiconv libtool make ninja pkg-config python rust sed unzip ruby ``` ```bash Fedora -$ sudo dnf install cargo ccache cmake git golang libtool ninja-build pkg-config rustc ruby libatomic-static libstdc++-static sed unzip which libicu-devel 'perl(Math::BigInt)' +$ sudo dnf install cargo clang19 llvm19 lld19 cmake git golang libtool ninja-build pkg-config rustc ruby libatomic-static libstdc++-static sed unzip which libicu-devel 'perl(Math::BigInt)' ``` ```bash openSUSE Tumbleweed @@ -56,6 +70,46 @@ $ brew install bun +### Optional: Install `sccache` + +sccache is used to cache compilation artifacts, significantly speeding up builds. It must be installed with S3 support: + +```bash +# For macOS +$ brew install sccache + +# For Linux. Note that the version in your package manager may not have S3 support. +$ cargo install sccache --features=s3 +``` + +This will install `sccache` with S3 support. Our build scripts will automatically detect and use `sccache` with our shared S3 cache. **Note**: Not all versions of `sccache` are compiled with S3 support, hence we recommend installing it via `cargo`. + +#### Registering AWS Credentials for `sccache` (Core Developers Only) + +Core developers have write access to the shared S3 cache. To enable write access, you must log in with AWS credentials. The easiest way to do this is to use the [`aws` CLI](https://aws.amazon.com/cli/) and invoke [`aws configure` to provide your AWS security info](https://docs.aws.amazon.com/cli/latest/reference/configure/). + +The `cmake` scripts should automatically detect your AWS credentials from the environment or the `~/.aws/credentials` file. + +
+ Logging in to the `aws` CLI + + 1. Install the AWS CLI by following [the official guide](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html). + 2. Log in to your AWS account console. A team member should provide you with your credentials. + 3. Click your name in the top right > Security credentials. + 4. Scroll to "Access keys" and create a new access key. + 5. Run `aws configure` in your terminal and provide the access key ID and secret access key when prompted. + +
+ +
+ Common Issues You May Encounter + + - To confirm that the cache is being used, you can use the `sccache --show-stats` command right after a build. This will expose very useful statistics, including cache hits/misses. + - If you have multiple AWS profiles configured, ensure that the correct profile is set in the `AWS_PROFILE` environment variable. + - `sccache` follows a server-client model. If you run into weird issues where `sccache` refuses to use S3, even though you have AWS credentials configured, try killing any running `sccache` servers with `sccache --stop-server` and then re-running the build. + +
+ ## Install LLVM Bun requires LLVM 19 (`clang` is part of LLVM). This version requirement is to match WebKit (precompiled), as mismatching versions will cause memory allocation failures at runtime. In most cases, you can install LLVM through your system package manager: @@ -156,7 +210,7 @@ Bun generally takes about 2.5 minutes to compile a debug build when there are Zi - Batch up your changes - Ensure zls is running with incremental watching for LSP errors (if you use VSCode and install Zig and run `bun run build` once to download Zig, this should just work) - Prefer using the debugger ("CodeLLDB" in VSCode) to step through the code. -- Use debug logs. `BUN_DEBUG_=1` will enable debug logging for the corresponding `Output.scoped(., false)` logs. You can also set `BUN_DEBUG_QUIET_LOGS=1` to disable all debug logging that isn't explicitly enabled. To dump debug lgos into a file, `BUN_DEBUG=.log`. Debug logs are aggressively removed in release builds. +- Use debug logs. `BUN_DEBUG_=1` will enable debug logging for the corresponding `Output.scoped(., .hidden)` logs. You can also set `BUN_DEBUG_QUIET_LOGS=1` to disable all debug logging that isn't explicitly enabled. To dump debug logs into a file, `BUN_DEBUG=.log`. Debug logs are aggressively removed in release builds. - src/js/\*\*.ts changes are pretty much instant to rebuild. C++ changes are a bit slower, but still much faster than the Zig code (Zig is one compilation unit, C++ is many). ## Code generation scripts @@ -327,15 +381,6 @@ bun run build -DUSE_STATIC_LIBATOMIC=OFF The built version of Bun may not work on other systems if compiled this way. -### ccache conflicts with building TinyCC on macOS - -If you run into issues with `ccache` when building TinyCC, try reinstalling ccache - -```bash -brew uninstall ccache -brew install ccache -``` - ## Using bun-debug - Disable logging: `BUN_DEBUG_QUIET_LOGS=1 bun-debug ...` (to disable all debug logging) diff --git a/docs/project/license.mdx b/docs/project/license.mdx index 679ff7be84..fa51203c26 100644 --- a/docs/project/license.mdx +++ b/docs/project/license.mdx @@ -11,7 +11,7 @@ Bun statically links JavaScriptCore (and WebKit) which is LGPL-2 licensed. WebCo > (1) If you statically link against an LGPL'd library, you must also provide your application in an object (not necessarily source) format, so that a user has the opportunity to modify the library and relink the application. -You can find the patched version of WebKit used by Bun here: [https://github.com/oven-sh/webkit](https://github.com/oven-sh/webkit). If you would like to relink Bun with changes: +You can find the patched version of WebKit used by Bun here: https://github.com/oven-sh/webkit. If you would like to relink Bun with changes: - `git submodule update --init --recursive` - `make jsc` diff --git a/docs/quickstart.mdx b/docs/quickstart.mdx index 21509db9f7..6781199996 100644 --- a/docs/quickstart.mdx +++ b/docs/quickstart.mdx @@ -92,7 +92,7 @@ Build a minimal HTTP server with `Bun.serve`, run it locally, then evolve it by Then add the following to your `compilerOptions` in `tsconfig.json`: - ```json tsconfig.json icon="file-code" + ```json tsconfig.json icon="file-json" { "compilerOptions": { "lib": ["ESNext"], @@ -219,16 +219,21 @@ Build a minimal HTTP server with `Bun.serve`, run it locally, then evolve it by Bun can also execute `"scripts"` from your `package.json`. Add the following script: -```json package.json icon="file-code" +{/* prettier-ignore */} +```json package.json icon="file-json" { "name": "quickstart", "module": "index.ts", "type": "module", - "scripts": { - "start": "bun run index.ts" - }, + "private": true, + "scripts": { // [!code ++] + "start": "bun run index.ts" // [!code ++] + }, // [!code ++] "devDependencies": { "@types/bun": "latest" + }, + "peerDependencies": { + "typescript": "^5" } } ``` diff --git a/docs/runtime/bunfig.mdx b/docs/runtime/bunfig.mdx index 57fb1805f0..2ed368d9ba 100644 --- a/docs/runtime/bunfig.mdx +++ b/docs/runtime/bunfig.mdx @@ -107,7 +107,9 @@ Bun supports the following loaders: ### `telemetry` -The `telemetry` field permit to enable/disable the analytics records. Bun records bundle timings (so we can answer with data, "is Bun getting faster?") and feature usage (e.g., "are people actually using macros?"). The request body size is about 60 bytes, so it's not a lot of data. By default the telemetry is enabled. Equivalent of `DO_NOT_TRACK` env variable. +The `telemetry` field is used to enable/disable analytics. By default, telemetry is enabled. This is equivalent to the `DO_NOT_TRACK` environment variable. + +Currently we do not collect telemetry and this setting is only used for enabling/disabling anonymous crash reports, but in the future we plan to collect information like which Bun APIs are used most or how long `bun build` takes. ```toml title="bunfig.toml" icon="settings" telemetry = false @@ -276,6 +278,58 @@ This is useful for catching flaky tests or non-deterministic behavior. Each test The `--rerun-each` CLI flag will override this setting when specified. +### `test.concurrentTestGlob` + +Specify a glob pattern to automatically run matching test files with concurrent test execution enabled. Test files matching this pattern will behave as if the `--concurrent` flag was passed, running all tests within those files concurrently. + +```toml title="bunfig.toml" icon="settings" +[test] +concurrentTestGlob = "**/concurrent-*.test.ts" +``` + +This is useful for: + +- Gradually migrating test suites to concurrent execution +- Running integration tests concurrently while keeping unit tests sequential +- Separating fast concurrent tests from tests that require sequential execution + +The `--concurrent` CLI flag will override this setting when specified. + +### `test.onlyFailures` + +When enabled, only failed tests are displayed in the output. This helps reduce noise in large test suites by hiding passing tests. Default `false`. + +```toml title="bunfig.toml" icon="settings" +[test] +onlyFailures = true +``` + +This is equivalent to using the `--only-failures` flag when running `bun test`. + +### `test.reporter` + +Configure the test reporter settings. + +#### `test.reporter.dots` + +Enable the dots reporter, which displays a compact output showing a dot for each test. Default `false`. + +```toml title="bunfig.toml" icon="settings" +[test.reporter] +dots = true +``` + +#### `test.reporter.junit` + +Enable JUnit XML reporting and specify the output file path. + +```toml title="bunfig.toml" icon="settings" +[test.reporter] +junit = "test-results.xml" +``` + +This generates a JUnit XML report that can be consumed by CI systems and other tools. + ## Package manager Package management is a complex issue; to support a range of use cases, the behavior of `bun install` can be configured under the `[install]` section. @@ -400,8 +454,8 @@ To configure the directory where Bun installs globally installed binaries and CL Environment variable: `BUN_INSTALL_BIN` ```toml title="bunfig.toml" icon="settings" -# where globally-installed package bins are linked [install] +# where globally-installed package bins are linked globalBinDir = "~/.bun/bin" ``` @@ -533,6 +587,32 @@ editor = "code" # - "emacs" ``` +### `install.security.scanner` + +Configure a security scanner to scan packages for vulnerabilities before installation. + +First, install a security scanner from npm: + +```bash terminal icon="terminal" +bun add -d @acme/bun-security-scanner +``` + +Then configure it in your `bunfig.toml`: + +```toml bunfig.toml icon="settings" +[install.security] +scanner = "@acme/bun-security-scanner" +``` + +When a security scanner is configured: + +- Auto-install is automatically disabled for security +- Packages are scanned before installation +- Installation is cancelled if fatal issues are found +- Security warnings are displayed during installation + +Learn more about [using and writing security scanners](/pm/security-scanner-api). + ### `install.minimumReleaseAge` Configure a minimum age (in seconds) for npm package versions. Package versions published more recently than this threshold will be filtered out during installation. Default is `null` (disabled). @@ -551,7 +631,7 @@ For more details see [Minimum release age](/pm/cli/install#minimum-release-age) The `bun run` command can be configured under the `[run]` section. These apply to the `bun run` command and the `bun` command when running a file or executable or script. -Currently, `bunfig.toml` isn't always automatically loaded for `bun run` in a local project (it does check for a global `bunfig.toml`), so you might still need to pass `-c` or `-c=bunfig.toml` to use these settings. +Currently, `bunfig.toml` is only automatically loaded for `bun run` in a local project (it doesn't check for a global `.bunfig.toml`). ### `run.shell` - use the system shell or Bun's shell diff --git a/docs/runtime/c-compiler.mdx b/docs/runtime/c-compiler.mdx index 14c0e27216..516fc3efbd 100644 --- a/docs/runtime/c-compiler.mdx +++ b/docs/runtime/c-compiler.mdx @@ -13,7 +13,7 @@ See the [introduction blog post](https://bun.com/blog/compile-and-run-c-in-js) f JavaScript: -```ts hello.js icon="file-code" +```ts hello.ts icon="file-code" import { cc } from "bun:ffi"; import source from "./hello.c" with { type: "file" }; @@ -87,7 +87,7 @@ You can also pass a `napi_env` to receive the N-API environment used to call the For example, if you have a string in C, you can return it to JavaScript like this: -```ts hello.js +```ts hello.ts import { cc } from "bun:ffi"; import source from "./hello.c" with { type: "file" }; diff --git a/docs/runtime/child-process.mdx b/docs/runtime/child-process.mdx index 6be68a6f27..a1b7ef9b2c 100644 --- a/docs/runtime/child-process.mdx +++ b/docs/runtime/child-process.mdx @@ -100,7 +100,7 @@ You can read results from the subprocess via the `stdout` and `stderr` propertie ```ts const proc = Bun.spawn(["bun", "--version"]); const text = await proc.stdout.text(); -console.log(text); // => "1.3.2\n" +console.log(text); // => "1.3.3\n" ``` Configure the output stream by passing one of the following values to `stdout/stderr`: @@ -289,7 +289,7 @@ childProc.disconnect(); To use IPC between a `bun` process and a Node.js process, set `serialization: "json"` in `Bun.spawn`. This is because Node.js and Bun use different JavaScript engines with different object serialization formats. -```ts bun-node-ipc.js icon="file-code" +```js bun-node-ipc.js icon="file-code" if (typeof Bun !== "undefined") { const prefix = `[bun ${process.versions.bun} 🐇]`; const node = Bun.spawn({ diff --git a/docs/runtime/cookies.mdx b/docs/runtime/cookies.mdx index 641dfc7989..0d90bd0420 100644 --- a/docs/runtime/cookies.mdx +++ b/docs/runtime/cookies.mdx @@ -9,7 +9,7 @@ Bun provides native APIs for working with HTTP cookies through `Bun.Cookie` and `Bun.CookieMap` provides a Map-like interface for working with collections of cookies. It implements the `Iterable` interface, allowing you to use it with `for...of` loops and other iteration methods. -```ts filename="cookies.ts" icon="/icons/typescript.svg" +```ts title="cookies.ts" icon="/icons/typescript.svg" // Empty cookie map const cookies = new Bun.CookieMap(); @@ -33,7 +33,7 @@ const cookies3 = new Bun.CookieMap([ In Bun's HTTP server, the `cookies` property on the request object (in `routes`) is an instance of `CookieMap`: -```ts filename="server.ts" icon="/icons/typescript.svg" +```ts title="server.ts" icon="/icons/typescript.svg" const server = Bun.serve({ routes: { "/": req => { @@ -68,7 +68,7 @@ console.log("Server listening at: " + server.url); Retrieves a cookie by name. Returns `null` if the cookie doesn't exist. -```ts filename="get-cookie.ts" icon="/icons/typescript.svg" +```ts title="get-cookie.ts" icon="/icons/typescript.svg" // Get by name const cookie = cookies.get("session"); @@ -81,7 +81,7 @@ if (cookie != null) { Checks if a cookie with the given name exists. -```ts filename="has-cookie.ts" icon="/icons/typescript.svg" +```ts title="has-cookie.ts" icon="/icons/typescript.svg" // Check if cookie exists if (cookies.has("session")) { // Cookie exists @@ -96,7 +96,7 @@ if (cookies.has("session")) { Adds or updates a cookie in the map. Cookies default to `{ path: "/", sameSite: "lax" }`. -```ts filename="set-cookie.ts" icon="/icons/typescript.svg" +```ts title="set-cookie.ts" icon="/icons/typescript.svg" // Set by name and value cookies.set("session", "abc123"); @@ -119,7 +119,7 @@ cookies.set(cookie); Removes a cookie from the map. When applied to a Response, this adds a cookie with an empty string value and an expiry date in the past. A cookie will only delete successfully on the browser if the domain and path is the same as it was when the cookie was created. -```ts filename="delete-cookie.ts" icon="/icons/typescript.svg" +```ts title="delete-cookie.ts" icon="/icons/typescript.svg" // Delete by name using default domain and path. cookies.delete("session"); @@ -135,7 +135,7 @@ cookies.delete({ Converts the cookie map to a serializable format. -```ts filename="cookie-to-json.ts" icon="/icons/typescript.svg" +```ts title="cookie-to-json.ts" icon="/icons/typescript.svg" const json = cookies.toJSON(); ``` @@ -145,7 +145,7 @@ Returns an array of values for Set-Cookie headers that can be used to apply all When using `Bun.serve()`, you don't need to call this method explicitly. Any changes made to the `req.cookies` map are automatically applied to the response headers. This method is primarily useful when working with other HTTP server implementations. -```ts filename="node-server.js" icon="file-code" +```js title="node-server.js" icon="file-code" import { createServer } from "node:http"; import { CookieMap } from "bun"; @@ -172,7 +172,7 @@ server.listen(3000, () => { `CookieMap` provides several methods for iteration: -```ts filename="iterate-cookies.ts" icon="/icons/typescript.svg" +```ts title="iterate-cookies.ts" icon="/icons/typescript.svg" // Iterate over [name, cookie] entries for (const [name, value] of cookies) { console.log(`${name}: ${value}`); @@ -205,7 +205,7 @@ cookies.forEach((value, name) => { Returns the number of cookies in the map. -```ts filename="cookie-size.ts" icon="/icons/typescript.svg" +```ts title="cookie-size.ts" icon="/icons/typescript.svg" console.log(cookies.size); // Number of cookies ``` @@ -213,7 +213,7 @@ console.log(cookies.size); // Number of cookies `Bun.Cookie` represents an HTTP cookie with its name, value, and attributes. -```ts filename="cookie-class.ts" icon="/icons/typescript.svg" +```ts title="cookie-class.ts" icon="/icons/typescript.svg" import { Cookie } from "bun"; // Create a basic cookie @@ -243,7 +243,7 @@ const objCookie = new Bun.Cookie({ ### Constructors -```ts filename="constructors.ts" icon="/icons/typescript.svg" +```ts title="constructors.ts" icon="/icons/typescript.svg" // Basic constructor with name/value new Bun.Cookie(name: string, value: string); @@ -259,7 +259,7 @@ new Bun.Cookie(options: CookieInit); ### Properties -```ts filename="cookie-properties.ts" icon="/icons/typescript.svg" +```ts title="cookie-properties.ts" icon="/icons/typescript.svg" cookie.name; // string - Cookie name cookie.value; // string - Cookie value cookie.domain; // string | null - Domain scope (null if not specified) @@ -278,7 +278,7 @@ cookie.httpOnly; // boolean - Accessible only via HTTP (not JavaScript) Checks if the cookie has expired. -```ts filename="is-expired.ts" icon="/icons/typescript.svg" +```ts title="is-expired.ts" icon="/icons/typescript.svg" // Expired cookie (Date in the past) const expiredCookie = new Bun.Cookie("name", "value", { expires: new Date(Date.now() - 1000), @@ -302,7 +302,7 @@ console.log(sessionCookie.isExpired()); // false Returns a string representation of the cookie suitable for a `Set-Cookie` header. -```ts filename="serialize-cookie.ts" icon="/icons/typescript.svg" +```ts title="serialize-cookie.ts" icon="/icons/typescript.svg" const cookie = new Bun.Cookie("session", "abc123", { domain: "example.com", path: "/admin", @@ -322,7 +322,7 @@ console.log(cookie.toString()); Converts the cookie to a plain object suitable for JSON serialization. -```ts filename="cookie-json.ts" icon="/icons/typescript.svg" +```ts title="cookie-json.ts" icon="/icons/typescript.svg" const cookie = new Bun.Cookie("session", "abc123", { secure: true, httpOnly: true, @@ -349,7 +349,7 @@ const jsonString = JSON.stringify(cookie); Parses a cookie string into a `Cookie` instance. -```ts filename="parse-cookie.ts" icon="/icons/typescript.svg" +```ts title="parse-cookie.ts" icon="/icons/typescript.svg" const cookie = Bun.Cookie.parse("name=value; Path=/; Secure; SameSite=Lax"); console.log(cookie.name); // "name" @@ -363,7 +363,7 @@ console.log(cookie.sameSite); // "lax" Factory method to create a cookie. -```ts filename="cookie-from.ts" icon="/icons/typescript.svg" +```ts title="cookie-from.ts" icon="/icons/typescript.svg" const cookie = Bun.Cookie.from("session", "abc123", { httpOnly: true, secure: true, @@ -373,7 +373,7 @@ const cookie = Bun.Cookie.from("session", "abc123", { ## Types -```ts filename="types.ts" icon="/icons/typescript.svg" +```ts title="types.ts" icon="/icons/typescript.svg" interface CookieInit { name?: string; value?: string; diff --git a/docs/runtime/debugger.mdx b/docs/runtime/debugger.mdx index c718f2632f..820a1a43d1 100644 --- a/docs/runtime/debugger.mdx +++ b/docs/runtime/debugger.mdx @@ -115,7 +115,7 @@ Here's a cheat sheet explaining the functions of the control flow buttons. ### Visual Studio Code Debugger -Experimental support for debugging Bun scripts is available in Visual Studio Code. To use it, you'll need to install the [Bun VSCode extension](https://bun.com/guides/runtime/vscode-debugger). +Experimental support for debugging Bun scripts is available in Visual Studio Code. To use it, you'll need to install the [Bun VSCode extension](/guides/runtime/vscode-debugger). --- @@ -146,11 +146,11 @@ await fetch("https://example.com", { ``` ```txt -[fetch] $ curl --http1.1 "https://example.com/" -X POST -H "content-type: application/json" -H "Connection: keep-alive" -H "User-Agent: Bun/1.3.2" -H "Accept: */*" -H "Host: example.com" -H "Accept-Encoding: gzip, deflate, br" --compressed -H "Content-Length: 13" --data-raw "{\"foo\":\"bar\"}" +[fetch] $ curl --http1.1 "https://example.com/" -X POST -H "content-type: application/json" -H "Connection: keep-alive" -H "User-Agent: Bun/1.3.3" -H "Accept: */*" -H "Host: example.com" -H "Accept-Encoding: gzip, deflate, br" --compressed -H "Content-Length: 13" --data-raw "{\"foo\":\"bar\"}" [fetch] > HTTP/1.1 POST https://example.com/ [fetch] > content-type: application/json [fetch] > Connection: keep-alive -[fetch] > User-Agent: Bun/1.3.2 +[fetch] > User-Agent: Bun/1.3.3 [fetch] > Accept: */* [fetch] > Host: example.com [fetch] > Accept-Encoding: gzip, deflate, br @@ -190,7 +190,7 @@ await fetch("https://example.com", { [fetch] > HTTP/1.1 POST https://example.com/ [fetch] > content-type: application/json [fetch] > Connection: keep-alive -[fetch] > User-Agent: Bun/1.3.2 +[fetch] > User-Agent: Bun/1.3.3 [fetch] > Accept: */* [fetch] > Host: example.com [fetch] > Accept-Encoding: gzip, deflate, br diff --git a/docs/runtime/environment-variables.mdx b/docs/runtime/environment-variables.mdx index c1b38edc1b..087da9ef56 100644 --- a/docs/runtime/environment-variables.mdx +++ b/docs/runtime/environment-variables.mdx @@ -13,7 +13,7 @@ Bun reads the following files automatically (listed in order of increasing prece - `.env.production`, `.env.development`, `.env.test` (depending on value of `NODE_ENV`) - `.env.local` -```txt .env icon="settings" +```ini .env icon="settings" FOO=hello BAR=world ``` @@ -46,7 +46,7 @@ bun exec 'FOO=helloworld bun run dev' On Windows, `package.json` scripts called with `bun run` will automatically use the **bun shell**, making the following also cross-platform. -```json package.json +```json package.json icon="file-json" "scripts": { "dev": "NODE_ENV=development bun --watch app.ts", }, @@ -72,13 +72,30 @@ bun --env-file=.env.1 src/index.ts bun --env-file=.env.abc --env-file=.env.def run build ``` +## Disabling automatic `.env` loading + +Use `--no-env-file` to disable Bun's automatic `.env` file loading. This is useful in production environments or CI/CD pipelines where you want to rely solely on system environment variables. + +```sh +bun run --no-env-file index.ts +``` + +This can also be configured in `bunfig.toml`: + +```toml bunfig.toml icon="settings" +# Disable loading .env files +env = false +``` + +Explicitly provided environment files via `--env-file` will still be loaded even when default loading is disabled. + --- ## Quotation marks Bun supports double quotes, single quotes, and template literal backticks: -```txt .env icon="settings" +```ini .env icon="settings" FOO='hello' FOO="hello" FOO=`hello` @@ -88,7 +105,7 @@ FOO=`hello` Environment variables are automatically _expanded_. This means you can reference previously-defined variables in your environment variables. -```txt .env icon="settings" +```ini .env icon="settings" FOO=world BAR=hello$FOO ``` @@ -99,7 +116,7 @@ process.env.BAR; // => "helloworld" This is useful for constructing connection strings or other compound values. -```txt .env icon="settings" +```ini .env icon="settings" DB_USER=postgres DB_PASSWORD=secret DB_HOST=localhost @@ -109,7 +126,7 @@ DB_URL=postgres://$DB_USER:$DB_PASSWORD@$DB_HOST:$DB_PORT/$DB_NAME This can be disabled by escaping the `$` with a backslash. -```txt .env icon="settings" +```ini .env icon="settings" FOO=world BAR=hello\$FOO ``` diff --git a/docs/runtime/html-rewriter.mdx b/docs/runtime/html-rewriter.mdx index cdddae9e1a..5e05ee0706 100644 --- a/docs/runtime/html-rewriter.mdx +++ b/docs/runtime/html-rewriter.mdx @@ -46,29 +46,22 @@ console.log(result); This replaces all images with a thumbnail of Rick Astley and wraps each `` in a link, producing a diff like this: +{/* prettier-ignore */} ```html - // [!code --] // [!code --] - // [!code --] - - // [!code ++] - Definitely not a rickroll - // [!code ++] - - // [!code ++] - - // [!code ++] - Definitely not a rickroll - // [!code ++] - - // [!code ++] - - // [!code ++] - Definitely not a rickroll - // [!code ++] - - // [!code ++] + + + + + Definitely not a rickroll + + + Definitely not a rickroll + + + Definitely not a rickroll + ``` diff --git a/docs/runtime/http/routing.mdx b/docs/runtime/http/routing.mdx index 06af0a2cbb..418e421866 100644 --- a/docs/runtime/http/routing.mdx +++ b/docs/runtime/http/routing.mdx @@ -102,7 +102,7 @@ Bun.serve({ TypeScript parses route parameters when passed as a string literal, so that your editor will show autocomplete when accessing `request.params`. -```ts title="index.ts" +```ts title="index.ts" icon="/icons/typescript.svg" import type { BunRequest } from "bun"; Bun.serve({ @@ -283,7 +283,7 @@ You can also access the `Server` object from the `fetch` handler. It's the secon const server = Bun.serve({ fetch(req, server) { const ip = server.requestIP(req); - return new Response(`Your IP is ${ip}`); + return new Response(`Your IP is ${ip.address}`); }, }); ``` diff --git a/docs/runtime/http/server.mdx b/docs/runtime/http/server.mdx index f230f1e7ea..59083df7f2 100644 --- a/docs/runtime/http/server.mdx +++ b/docs/runtime/http/server.mdx @@ -32,12 +32,8 @@ const server = Bun.serve({ // Redirect from /blog/hello to /blog/hello/world "/blog/hello": Response.redirect("/blog/hello/world"), - // Serve a file by buffering it in memory - "/favicon.ico": new Response(await Bun.file("./favicon.ico").bytes(), { - headers: { - "Content-Type": "image/x-icon", - }, - }), + // Serve a file by lazily loading it into memory + "/favicon.ico": Bun.file("./favicon.ico"), }, // (optional) fallback for unmatched routes: @@ -126,7 +122,7 @@ bun --port=4002 server.ts - `BUN_PORT` environment variable ```sh -bun_PORT=4002 bun server.ts +BUN_PORT=4002 bun server.ts ``` - `PORT` environment variable diff --git a/docs/runtime/http/websockets.mdx b/docs/runtime/http/websockets.mdx index 174043200d..657da9f40b 100644 --- a/docs/runtime/http/websockets.mdx +++ b/docs/runtime/http/websockets.mdx @@ -107,13 +107,13 @@ Bun.serve({ Once the upgrade succeeds, Bun will send a `101 Switching Protocols` response per the [spec](https://developer.mozilla.org/en-US/docs/Web/HTTP/Protocol_upgrade_mechanism). Additional `headers` can be attached to this `Response` in the call to `server.upgrade()`. +{/* prettier-ignore */} ```ts server.ts icon="/icons/typescript.svg" Bun.serve({ fetch(req, server) { const sessionId = await generateSessionId(); server.upgrade(req, { - headers: { - // [!code ++] + headers: { // [!code ++] "Set-Cookie": `SessionId=${sessionId}`, // [!code ++] }, // [!code ++] }); @@ -126,6 +126,8 @@ Bun.serve({ Contextual `data` can be attached to a new WebSocket in the `.upgrade()` call. This data is made available on the `ws.data` property inside the WebSocket handlers. +To strongly type `ws.data`, add a `data` property to the `websocket` handler object. This types `ws.data` across all lifecycle hooks. + ```ts server.ts icon="/icons/typescript.svg" type WebSocketData = { createdAt: number; @@ -166,9 +168,13 @@ Bun.serve({ }); ``` + +**Note:** Previously, you could specify the type of `ws.data` using a type parameter on `Bun.serve`, like `Bun.serve({...})`. This pattern was removed due to [a limitation in TypeScript](https://github.com/microsoft/TypeScript/issues/26242) in favor of the `data` property shown above. + + To connect to this server from the browser, create a new `WebSocket`. -```ts browser.js icon="file-code" +```js browser.js icon="file-code" const socket = new WebSocket("ws://localhost:3000/chat"); socket.addEventListener("message", event => { diff --git a/docs/runtime/index.mdx b/docs/runtime/index.mdx index 7ffa1d0a9b..9a01aa2e73 100644 --- a/docs/runtime/index.mdx +++ b/docs/runtime/index.mdx @@ -94,7 +94,7 @@ Cleaning... Done. ``` -Bun executes the script command in a subshell. On Linux & macOS, it checks for the following shells in order, using the first one it finds: `bash`, `sh`, `zsh`. On windows, it uses [bun shell](https://bun.com/docs/runtime/shell) to support bash-like syntax and many common commands. +Bun executes the script command in a subshell. On Linux & macOS, it checks for the following shells in order, using the first one it finds: `bash`, `sh`, `zsh`. On Windows, it uses [bun shell](/runtime/shell) to support bash-like syntax and many common commands. ⚡️ The startup time for `npm run` on Linux is roughly 170ms; with Bun it is `6ms`. @@ -153,7 +153,7 @@ bun run --filter 'ba*'