Compare commits

...

131 Commits

Author SHA1 Message Date
Jarred-Sumner
7523ac9c52 deps: update elysia to 1.4.19 (1.4.19) 2025-12-14 04:16:01 +00:00
Ciro Spaciari
a5712b92b8 Fix 100% CPU usage with idle WebSocket connections on macOS (kqueue) (#25475)
### What does this PR do?

Fixes a bug where idle WebSocket connections would cause 100% CPU usage
on macOS and other BSD systems using kqueue.

**Root cause:** The kqueue event filter comparison was using bitwise AND
(`&`) instead of equality (`==`) when checking the filter type. Combined
with missing `EV_ONESHOT` flags on writable events, this caused the
event loop to continuously spin even when no actual I/O was pending.

**Changes:**
1. **Fixed filter comparison** in `epoll_kqueue.c`: Changed `filter &
EVFILT_READ` to `filter == EVFILT_READ` (same for `EVFILT_WRITE`). The
filter field is a value, not a bitmask.

2. **Added `EV_ONESHOT` flag** to writable events: kqueue writable
events now use one-shot mode to prevent continuous triggering.

3. **Re-arm writable events when needed**: After a one-shot writable
event fires, the code now properly updates the poll state and re-arms
the writable event if another write is still pending.

### How did you verify your code works?

Added a test that:
1. Creates a TLS WebSocket server and client
2. Sends messages then lets the connection sit idle
3. Measures CPU usage over 3 seconds
4. Fails if CPU usage exceeds 2% (expected is ~0.XX% when idle)
2025-12-12 11:10:22 -08:00
robobun
7dcd49f832 fix(install): only apply default trusted dependencies to npm packages (#25163)
## Summary
- The default trusted dependencies list should only apply to packages
installed from npm
- Non-npm sources (file:, link:, git:, github:) now require explicit
trustedDependencies
- This prevents malicious packages from spoofing trusted names through
local paths or git repos

## Test plan
- [x] Added test: file: dependency named "esbuild" does NOT auto-run
postinstall scripts
- [x] Added test: file: dependency runs scripts when explicitly added to
trustedDependencies
- [x] Verified tests fail with system bun (old behavior) and pass with
new build
- [x] Build compiles successfully

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
Co-authored-by: Dylan Conway <dylan.conway567@gmail.com>
2025-12-11 17:44:41 -08:00
robobun
c59a6997cd feat(bundler): add statically-analyzable dead-code elimination via feature flags (#25462)
## Summary
- Adds `import { feature } from "bun:bundle"` for compile-time feature
flag checking
- `feature("FLAG_NAME")` calls are replaced with `true`/`false` at
bundle time
- Enables dead-code elimination through `--feature=FLAG_NAME` CLI
argument
- Works in `bun build`, `bun run`, and `bun test`
- Available in both CLI and `Bun.build()` JavaScript API

## Usage

```ts
import { feature } from "bun:bundle";

if (feature("SUPER_SECRET")) {
  console.log("Secret feature enabled!");
} else {
  console.log("Normal mode");
}
```

### CLI
```bash
# Enable feature during build
bun build --feature=SUPER_SECRET index.ts

# Enable at runtime
bun run --feature=SUPER_SECRET index.ts

# Enable in tests
bun test --feature=SUPER_SECRET
```

### JavaScript API
```ts
await Bun.build({
  entrypoints: ['./index.ts'],
  outdir: './out',
  features: ['SUPER_SECRET', 'ANOTHER_FLAG'],
});
```

## Implementation
- Added `bundler_feature_flags` (as `*const bun.StringSet`) to
`RuntimeFeatures` and `BundleOptions`
- Added `bundler_feature_flag_ref` to Parser struct to track the
`feature` import
- Handle `bun:bundle` import at parse time (similar to macros) - capture
ref, return empty statement
- Handle `feature()` calls in `e_call` visitor - replace with boolean
based on flags
- Wire feature flags through CLI arguments and `Bun.build()` API to
bundler options
- Added `features` option to `JSBundler.zig` for JavaScript API support
- Added TypeScript types in `bun.d.ts`
- Added documentation to `docs/bundler/index.mdx`

## Test plan
- [x] Basic feature flag enabled/disabled tests (both CLI and API
backends)
- [x] Multiple feature flags test
- [x] Dead code elimination verification tests
- [x] Error handling for invalid arguments
- [x] Runtime tests with `bun run --feature=FLAG`
- [x] Test runner tests with `bun test --feature=FLAG`
- [x] Aliased import tests (`import { feature as checkFeature }`)
- [x] Ternary operator DCE tests
- [x] Tests use `itBundled` with both `backend: "cli"` and `backend:
"api"`

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Alistair Smith <hi@alistair.sh>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-12-11 17:44:14 -08:00
Alistair Smith
1d50af7fe8 @types/bun: Update to @types/node@25, fallback to PropertyKey in test expect matchers when keyof unknown is used (#25460)
more accurately, developers cannot pass a value when expect values
resolve to never. this is easy to fall into when using the
`toContainKey*` matchers. falling back to PropertyKey when this happens
is a sensible/reasonable default

### What does this PR do?

fixes #25456, cc @MonsterDeveloper
fixes #25461

### How did you verify your code works?

bun types integration test
2025-12-10 18:15:55 -08:00
Jarred Sumner
98cee5a57e Improve Bun.stringWidth accuracy and robustness (#25447)
This PR significantly improves `Bun.stringWidth` to handle a wider
variety of Unicode characters and escape sequences correctly.

## Zero-width character handling

Added support for many previously unhandled zero-width characters:
- Soft hyphen (U+00AD)
- Word joiner and invisible operators (U+2060-U+2064)
- Lone surrogates (U+D800-U+DFFF)
- Arabic formatting characters (U+0600-U+0605, U+06DD, U+070F, U+08E2)
- Indic script combining marks (Devanagari through Malayalam)
- Thai and Lao combining marks
- Combining Diacritical Marks Extended and Supplement
- Tag characters (U+E0000-U+E007F)

## ANSI escape sequence handling

### CSI sequences
- Now properly handles ALL CSI final bytes (0x40-0x7E), not just `m`
- This means cursor movement (A/B/C/D), erase (J/K), scroll (S/T), and
other CSI commands are now correctly excluded from width calculation

### OSC sequences
- Added support for OSC sequences (ESC ] ... BEL/ST)
- OSC 8 hyperlinks are now properly handled
- Supports both BEL (0x07) and ST (ESC \) terminators

### ESC ESC fix
- Fixed state machine bug where `ESC ESC` would incorrectly reset state
- Now correctly handles consecutive ESC characters

## Emoji handling

Added proper grapheme-aware emoji width calculation:
- Flag emoji (regional indicator pairs) → width 2
- Skin tone modifiers → width 2
- ZWJ sequences (family, professions, etc.) → width 2
- Keycap sequences → width 2
- Variation selectors (VS15 for text, VS16 for emoji presentation)
- Uses ICU's `UCHAR_EMOJI` property for accurate emoji detection

## Test coverage

Added comprehensive test suite with **94 tests** covering:
- All zero-width character categories
- All CSI final bytes
- OSC sequences with various terminators
- Emoji edge cases (flags, skin tones, ZWJ, keycaps, variation
selectors)
- East Asian width (CJK, fullwidth, halfwidth katakana)
- Indic and Thai script combining marks
- Fuzzer-like stress tests for robustness

## Breaking changes

This is a behavior change - `stringWidth` will return different values
for some inputs. However, the new values are more accurate
representations of terminal display width:

| Input | Old | New | Why |
|-------|-----|-----|-----|
| Flag emoji 🇺🇸 | 1 | 2 | Flags display as 2 cells |
| Skin tone 👋🏽 | 4 | 2 | Emoji + modifier = 1 grapheme |
| ZWJ family 👨‍👩‍👧 | 8 | 2 | ZWJ sequence = 1 grapheme |
| Word joiner U+2060 | 1 | 0 | Invisible character |
| OSC 8 hyperlinks | counted URL | just visible text | URLs are
invisible |
| Cursor movement ESC[5A | counted | 0 | Control sequence |

🤖 Generated with [Claude Code](https://claude.ai/code)

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Claude Bot <claude-bot@bun.sh>
2025-12-10 16:17:57 -08:00
Elfayeur - Remi
ac0099ebc6 docs: fix code highlight (#25411)
### What does this PR do?

Fix code highlight line, see problem:
<img width="684" height="663" alt="Screenshot 2025-12-08 at 11 40 39 AM"
src="https://github.com/user-attachments/assets/9894a7b7-ddd6-4bad-b7de-3e0e55ecd8cd"
/>


### How did you verify your code works?

Co-authored-by: Michael H <git@riskymh.dev>
2025-12-10 16:06:45 +11:00
Ryan Machado
64146d47f9 Update os-signals.mdx (#25372)
### What does this PR do?

Remove a loose section from os-signals documentation

### How did you verify your code works?

Just a small documentation change.

Co-authored-by: Michael H <git@riskymh.dev>
2025-12-10 16:06:39 +11:00
robobun
a2d8b75962 fix(yaml): quote strings ending with colons (#25443)
## Summary
- Fixes strings ending with colons (e.g., `"tin:"`) not being quoted in
YAML.stringify output
- This caused YAML.parse to fail with "Unexpected token" when parsing
the output back

## Test plan
- Added regression tests in `test/regression/issue/25439.test.ts`
- Verified round-trip works for various strings ending with colons
- Ran existing YAML tests to ensure no regressions

Fixes #25439

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-09 18:20:26 -08:00
Kyle
a15fe76bf2 add brotli and zstd to CompressionStream and DecompressionStream types (#25374)
### What does this PR do?

- removes the `Unimplemented in Bun` comment on `CompressionStream` and
`DecompressionStream`
- updates the types for `CompressionStream` and `DecompressionStream` to
add a new internal `CompressionFormat` type to the constructor, which
adds `brotli` and `zstd` to the union
- adds tests for brotli and zstd usage
- adds lib.dom.d.ts exclusions for brotli and zstd as these don't exist
in the DOM version of CompressionFormat

fixes #25367

### How did you verify your code works?

typechecks and tests
2025-12-09 17:56:55 -08:00
robobun
8dc084af5f fix(fetch): ignore proxy object without url property (#25414)
## Summary
- When a URL object is passed as the proxy option, or when a proxy
object lacks a "url" property, ignore it instead of throwing an error
- This fixes a regression introduced in 1.3.4 where libraries like taze
that pass URL objects as proxy values would fail

## Test plan
- Added test: "proxy as URL object should be ignored (no url property)"
- passes a URL object directly as proxy
- Updated test: "proxy object without url is ignored (regression
#25413)" - proxy object with headers but no url
- Updated test: "proxy object with null url is ignored (regression
#25413)" - proxy object where url is null
- All 29 proxy tests pass

Fixes #25413

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-12-09 12:31:45 -08:00
Alistair Smith
2028e21d60 fmt bun.d.ts 2025-12-08 18:00:09 -08:00
Ciro Spaciari
f25ea59683 feat(s3): add Content-Disposition support for S3 uploads (#25363)
### What does this PR do?
- Add `contentDisposition` option to S3 file uploads to control the
`Content-Disposition` HTTP header
- Support passing `contentDisposition` through all S3 upload paths
(simple uploads, multipart uploads, and streaming uploads)
- Add TypeScript types for the new option
Fixes https://github.com/oven-sh/bun/issues/25362
### How did you verify your code works?
Test
2025-12-08 15:30:20 -08:00
Jarred Sumner
55c6afb498 Deflake test/js/bun/net/socket.test.ts 2025-12-08 11:16:26 -08:00
Jarred Sumner
0aca002161 Deflake test/js/bun/util/sleep.test.ts 2025-12-08 11:14:52 -08:00
robobun
4980736786 docs(server): fix satisfies Serve type in export default example (#25410) 2025-12-08 09:25:00 -08:00
robobun
3af0d23d53 docs: expand single-file executable file embedding documentation (#25408)
## Summary

- Expanded documentation for embedding files in single-file executables
with `with { type: "file" }`
- Added clear explanation of how the import attribute works and path
transformation at build time
- Added examples for reading embedded files with both `Bun.file()` and
Node.js `fs` APIs
- Added practical examples: JSON configs, HTTP static assets, templates,
binary files (WASM, fonts)
- Improved `Bun.embeddedFiles` section with a dynamic asset server
example

## Test plan

- [x] Verified all code examples compile and run correctly with `bun
build --compile`
- [x] Tested `Bun.file()` reads embedded files correctly
- [x] Tested `node:fs` APIs (`readFileSync`, `promises.readFile`,
`stat`) work with embedded files
- [x] Tested `Bun.embeddedFiles` returns correct blob array
- [x] Tested `--asset-naming` flag removes content hashes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-12-07 18:43:00 -08:00
Hamidreza Hanafi
9c96937329 fix(transpiler): preserve simplified property values in object spread expressions (#25401)
Fixes #25398

### What does this PR do?

Fixes a bug where object expressions with spread properties and nullish
coalescing to empty objects (e.g., `k?.x ?? {}`) would produce invalid
JavaScript output like `k?.x ?? ` (missing `{}`).

### Root Cause

In `src/ast/SideEffects.zig`, the `simplifyUnusedExpr` function handles
unused object expressions with spread properties. When simplifying
property values:

1. The code creates a mutable copy `prop` from the original `prop_`
2. When a property value is simplified (e.g., `k?.x ?? {}` → `k?.x`), it
updates `prop.value`
3. **Bug:** The code then wrote back `prop_` (the original) instead of
`prop` (the modified copy)

Because `simplifyUnusedExpr` mutates the AST in place when handling
nullish coalescing (setting `bin.right` to empty), the original `prop_`
now contained an expression with `bin.right` as an empty/missing
expression, resulting in invalid output.

### How did you verify your code works?
- Added regression test in `test/regression/issue/25398.test.ts`
- Verified the original reproduction case passes
- Verified existing CommonJS tests continue to pass
- Verified test fails with system bun and passes with the fix
2025-12-07 16:33:37 -08:00
robobun
d4eaaf8363 docs: document autoload options for standalone executables (#25385)
## Summary

- Document new default behavior in v1.3.4: `tsconfig.json` and
`package.json` loading is now disabled by default for standalone
executables
- Add documentation for `--compile-autoload-tsconfig` and
`--compile-autoload-package-json` CLI flags
- Document all four JavaScript API options: `autoloadTsconfig`,
`autoloadPackageJson`, `autoloadDotenv`, `autoloadBunfig`
- Note that `.env` and `bunfig.toml` may also be disabled by default in
a future version

## Test plan

- [ ] Review rendered documentation for accuracy and formatting

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-12-07 15:44:06 -08:00
Jarred Sumner
e1aa437694 Bump 2025-12-07 15:42:23 -08:00
robobun
73c3f0004f fix(vm): delete internal Loader property from node:vm global object (#25397) 2025-12-07 13:29:32 -08:00
robobun
b80cb629c6 fix(docs): correct mock documentation examples (#25384)
## Summary

- Fix `mock.mock.args` to `mock.mock.calls` in mock-functions.mdx (the
`.args` property doesn't exist)
- Fix mock.restore example to use module methods instead of spy
functions (calling spy functions after restore returns `undefined`)
- Add missing `vi` import in Vitest compatibility example

## Test plan

- [x] Verified each code block works by running tests against the debug
build

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-06 22:17:51 -08:00
Jarred Sumner
8773f7ab65 Delete TODO.md 2025-12-06 19:58:21 -08:00
Dylan Conway
5eb2145b31 fix(compile): use 8-byte header for embedded section to ensure bytecode alignment (#25377)
## Summary
- Change the size header in embedded Mach-O and PE sections from `u32`
(4 bytes) to `u64` (8 bytes)
- Ensures the data payload starts at an 8-byte aligned offset, which is
required for the bytecode cache

## Test plan
- [x] Test standalone compilation on macOS
- [ ] Test standalone compilation on Windows

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-06 16:37:09 -08:00
Jarred Sumner
cde167cacd Revert "Add Tanstack Start to bun init (#24648)"
Adding a 260 KB bun header image is not a good use of binary size

This reverts commit 830fd9b0ae.
2025-12-05 18:32:51 -08:00
robobun
6ce419d3f8 fix(napi): napi_typeof returns napi_object for String objects (#25365)
## Summary

- Fix `napi_typeof` to return `napi_object` for boxed String objects
(`new String("hello")`) instead of incorrectly returning `napi_string`
- Add regression test for boxed primitive objects (String, Number,
Boolean)

The issue was that `StringObjectType` and `DerivedStringObjectType` JSC
cell types were falling through to return `napi_string`, but these
represent object wrappers around strings, not primitive strings.

## Test plan

- [x] `bun bd test test/napi/napi.test.ts -t "napi_typeof"` passes
- [x] Test fails with `USE_SYSTEM_BUN=1` (confirming the bug exists in
released version)

Fixes #25351

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-05 18:27:06 -08:00
Alistair Smith
05508a627d Reapply "use event.message when no event.error in HMR during event" (#25360)
This reverts commit b4c8379447.

### What does this PR do?

### How did you verify your code works?

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-05 17:38:56 -08:00
robobun
23383b32b0 feat(compile): add --compile-autoload-tsconfig and --compile-autoload-package-json flags (#25340)
## Summary

By default, standalone executables no longer load `tsconfig.json` and
`package.json` at runtime. This improves startup performance and
prevents unexpected behavior from config files in the runtime
environment.

- Added `--compile-autoload-tsconfig` / `--no-compile-autoload-tsconfig`
CLI flags (default: false)
- Added `--compile-autoload-package-json` /
`--no-compile-autoload-package-json` CLI flags (default: false)
- Added `autoloadTsconfig` and `autoloadPackageJson` options to the
`Bun.build()` compile config
- Flags are stored in `StandaloneModuleGraph.Flags` and applied at
runtime boot

This follows the same pattern as the existing
`--compile-autoload-dotenv` and `--compile-autoload-bunfig` flags.

## Test plan

- [x] Added tests in `test/bundler/bundler_compile_autoload.test.ts`
- [x] Verified standalone executables work correctly with runtime config
files that differ from compile-time configs
- [x] Verified the new CLI flags are properly parsed and applied
- [x] Verified the JS API options work correctly

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-12-05 14:43:53 -08:00
eroderust
0d5a7c36ed chore: remove duplicate words in comment (#25347) 2025-12-05 11:19:47 -08:00
Alistair Smith
b4c8379447 Revert "use event.message when no event.error in HMR during event"
This reverts commit 438aaf9e95.
2025-12-05 11:16:52 -08:00
Alistair Smith
438aaf9e95 use event.message when no event.error in HMR during event 2025-12-05 11:14:45 -08:00
robobun
4d60b6f69d docs: clarify SQLite embed example requires existing database (#25329)
Co-authored-by: Alistair Smith <hi@alistair.sh>
2025-12-03 22:02:39 -08:00
pfg
e9e93244cb remove CMakeCache before building (#24860)
So it doesn't cache flags that are passed to the build
2025-12-01 22:02:46 -08:00
pfg
800a937cc2 Add fake timers for bun:test (#23764)
Fixes ENG-21288

TODO: Test with `@testing-library/react` `waitFor`

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 21:59:11 -08:00
Lydia Hallie
830fd9b0ae Add Tanstack Start to bun init (#24648)
Co-authored-by: Alistair Smith <hi@alistair.sh>
2025-12-01 21:05:47 -08:00
Meghan Denny
fe0aba79f4 test: add regression tests for building docker containers (#25210) 2025-12-01 20:20:06 -08:00
sdm2345
a4aaec5b2f Fix http.Agent connection pool not reusing connections (#24351)
This fixes a critical bug where `http.Agent` with `keepAlive: true` was
not reusing connections, causing a 66% performance degradation compared
to Node.js. Every request was establishing a new TCP/TLS connection
instead of reusing existing ones.

**Root Cause:**

Three independent bugs were causing the connection pool to fail:

1. **TypeScript layer** (`src/js/node/_http_client.ts:271`)
   - Reading wrong property: `keepalive` instead of `keepAlive`
   - User's `keepAlive: true` setting was being ignored

2. **Request header handling** (`src/http.zig:591`)
   - Only handled `Connection: close`, ignored `Connection: keep-alive`
   - Missing explicit flag update for keep-alive header

3. **Response header handling** (`src/http.zig:2240`)
   - Used compile-time function `eqlComptime` at runtime (always failed)
   - Inverted logic: disabled pool when NOT "keep-alive"
   - Ignored case-sensitivity (should use `eqlIgnoreCase` per RFC 7230)

**Performance Impact:**

- **Before**: All requests ~940ms, stddev 33ms (0% improvement) 
- **After**: First request ~930ms, subsequent ~320ms (65.9% improvement)

- Performance now matches Node.js (65.9% vs 66.5% improvement)
- QPS increased from 4.2 to 12.2 req/s (190% improvement)

**Files Changed:**
- `src/js/node/_http_client.ts` - Fix property name (1 line)
- `src/http.zig` - Fix request/response header handling (5 lines)

Fixes #12053

### What does this PR do?

This PR fixes the HTTP connection pool by correcting three bugs:

1. **Fixes TypeScript property name**: Changes `this[kAgent]?.keepalive`
to `this[kAgent]?.keepAlive` to properly read the user's keepAlive
setting from http.Agent

2. **Adds keep-alive request header handling**: Explicitly sets
`disable_keepalive = false` when receiving `Connection: keep-alive`
header

3. **Fixes response header parsing**: 
- Replaces compile-time `strings.eqlComptime()` with runtime
`std.ascii.eqlIgnoreCase()`
- Corrects inverted logic to properly enable connection pool on
`Connection: keep-alive`
   - Makes header comparison case-insensitive per RFC 7230

All three bugs must be fixed together - any single bug would cause the
connection pool to fail.

### How did you verify your code works?

**Test 1: Minimal reproduction with 10 sequential HTTPS requests**
```typescript
const agent = new https.Agent({ keepAlive: true });
// Make 10 requests to https://api.example.com
```

Results:
- First request: 930ms (cold start with TCP/TLS handshake)
- Subsequent requests: ~320ms average (connection reused)
- **Improvement: 65.9%** (matches Node.js 66.5%)
- Verified across 3 repeated test runs for stability

**Test 2: Response header validation**
- Confirmed server returns `Connection: Keep-Alive`
- Verified Bun correctly parses and applies the header

**Test 3: Performance comparison**

| Runtime | First Request | Subsequent Avg | Improvement | QPS |
|---------|--------------|----------------|-------------|-----|
| Node.js v20.18.0 | 938ms | 314ms | **66.5%** | 12.2 |
| Bun v1.3.1 (broken) | 935ms | 942ms | -0.7%  | 4.2 |
| Bun v1.3.2 (fixed) | 930ms | 317ms | **65.9%**  | 12.2 |

Bun now performs identically to Node.js, confirming the connection pool
works correctly.
2025-12-01 17:31:15 -08:00
Meghan Denny
24bc8aa416 ci: remove ubuntu 24 (#25288)
redundant with 25
2025-12-01 17:01:14 -08:00
robobun
2ab6efeea3 fix(ffi): restore CString constructor functionality (#25257)
## Summary
- Fix regression where `new Bun.FFI.CString(ptr)` throws "function is
not a constructor"
- Pass the same function as both call and constructor callbacks for
CString

## Root Cause
PR #24910 replaced `jsc.createCallback` with `jsc.JSFunction.create` for
all FFI functions. However, `JSFunction.create` doesn't allow
constructor calls by default (it uses `callHostFunctionAsConstructor`
which throws). The old `createCallback` used `JSFFIFunction` which
allowed the same function to be called with `new`.

## Fix
Pass the same function as both the `implementation` and `constructor`
option to `JSFunction.create` for CString specifically. This allows `new
CString(ptr)` to work while keeping the refactoring from #24910.

Additionally, the `bun:ffi` module now replaces `Bun.FFI.CString` with
the proper JS CString class after loading, so users get the full class
with `.ptr`, `.byteOffset`, etc. properties.

## Test plan
- [x] Added regression test `test/regression/issue/25231.test.ts`
- [x] Test fails with `USE_SYSTEM_BUN=1` (v1.3.3), passes with fix
- [x] Verified reproduction case from issue works

Fixes #25231

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 15:47:27 -08:00
Amdadul Haq
6745bdaa85 Add protocol property to serve.d.ts (#25267) 2025-12-01 13:43:14 -08:00
Lydia Hallie
dce7a02f4d Docs: Minor fixes and improvements (#25284)
This PR addresses several issues opened for the docs:

- Add callout for SQLite caching behavior between prepare() and query()
- Fix SQLite types and fix deprecated exec to run
- Fix Secrets API example
- Update SolidStart guide
- Add bun upgrade guide
- Prefer `process.versions.bun` over `typeof Bun` for detection
- Document complete `bunx` flags
- Improve Nitro preset documentation for Nuxt

Fixes #23165, #24424, #24294, #25175, #18433, #16804, #22967, #22527,
#10560, #14744
2025-12-01 13:32:08 -08:00
Michael H
9c420c9eff fix production build for vscode extention (#25274) 2025-12-01 12:59:27 -08:00
github-actions[bot]
9c2ca4b8fd deps: update sqlite to 3.51.100 (#25243)
## What does this PR do?

Updates SQLite to version 3.51.100

Compare: https://sqlite.org/src/vdiff?from=3.51.0&to=3.51.100

Auto-updated by [this
workflow](https://github.com/oven-sh/bun/actions/workflows/update-sqlite3.yml)

Co-authored-by: Jarred-Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2025-12-01 11:58:34 -08:00
robobun
e624f1e571 fix(jest): handle null SourceOrigin in jest.mock() to prevent crash (#25281)
## Summary
- Added null check for `sourceOrigin` before accessing its URL in
`jest.mock()`
- When `callerSourceOrigin()` returns null (e.g., when called with
invalid arguments), the code now safely returns early instead of
crashing

## Test plan
- [x] Added regression test `test/regression/issue/ENG-24434.test.ts`
- [x] `bun bd test test/regression/issue/ENG-24434.test.ts` passes

Fixes ENG-24434

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 11:54:03 -08:00
robobun
27381063b6 fix(windows): use GetConsoleCP() instead of GetConsoleOutputCP() for input codepage (#25252)
## Summary

- Fix typo where `GetConsoleOutputCP()` was called twice instead of
calling `GetConsoleCP()` for the input codepage
- Add missing `GetConsoleCP()` extern declaration in windows.zig

The code was saving the output codepage twice, meaning the input
codepage was never properly saved and thus couldn't be correctly
restored.

## Note

This fix corrects a bug in the codepage save/restore logic, but **may
not fully resolve the garbled text issue** in #25151. The garbled text
problem occurs when `bunx` (without `--bun`) runs a package via Node.js,
and that package tries to spawn `bun`. The error message from cmd.exe
gets garbled on non-English Windows systems.

Further investigation may be needed to determine if additional codepage
handling is required when spawning processes.

Related to #25151

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-11-30 23:11:33 -08:00
Michael H
9ca8de6eb9 vscode test runner add the new test functions to static analysis (#25256) 2025-11-30 17:31:17 -08:00
robobun
fdcfac6a75 fix(node:tls): use SSL_session_reused for TLSSocket.isSessionReused (#25258)
## Summary
Fixes `TLSSocket.isSessionReused()` to use BoringSSL's
`SSL_session_reused()` API instead of incorrectly checking if a session
was set.

The previous implementation returned `!!this[ksession]` which would
return `true` if `setSession()` was called, even if the session wasn't
actually reused by the SSL layer. This fix correctly uses the native SSL
API like Node.js does.

## Changes
- Added native `isSessionReused` function in Zig that calls
`SSL_session_reused()`
- Updated `TLSSocket.prototype.isSessionReused` to use the native
implementation
- Added regression tests

## Test plan
- [x] `bun bd test test/regression/issue/25190.test.ts` passes
- [x] `bun bd test test/js/node/tls/node-tls-connect.test.ts` passes

Fixes #25190

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-30 17:00:25 -08:00
robobun
ce1981c525 fix(node:assert): handle Number and Boolean wrappers in deepStrictEqual (#25201)
## Summary
- Fixes `assert.deepStrictEqual()` to properly compare Number and
Boolean wrapper objects
- Previously, `new Number(1)` and `new Number(2)` were incorrectly
considered equal because they have no enumerable properties
- Now correctly extracts and compares internal values using
`JSC::sameValue()`, then falls through to check own properties

## Test plan
- [x] Run `bun bd test test/regression/issue/24045.test.ts` - all 6
tests pass
- [x] Verify tests fail with system Bun (`USE_SYSTEM_BUN=1`) to confirm
fix validity
- [x] Verified behavior matches Node.js exactly (see table below)

## Node.js Compatibility

| Test Case | Node.js | Bun |
|-----------|---------|-----|
| Different Number values (`new Number(1)` vs `new Number(2)`) | throws
| throws |
| Same Number values (`new Number(1)` vs `new Number(1)`) | equal |
equal |
| 0 vs -0 (`new Number(0)` vs `new Number(-0)`) | throws | throws |
| NaN equals NaN (`new Number(NaN)` vs `new Number(NaN)`) | equal |
equal |
| Different Boolean values (`new Boolean(true)` vs `new Boolean(false)`)
| throws | throws |
| Same Boolean values | equal | equal |
| Number wrapper vs primitive (`new Number(1)` vs `1`) | throws | throws
|
| Number vs Boolean wrapper | throws | throws |
| Same value, different own properties | throws | throws |
| Same value, same own properties | equal | equal |
| Different own property values | throws | throws |

## Example

Before (bug):
```javascript
assert.deepStrictEqual(new Number(1), new Number(2)); // passes incorrectly
```

After (fixed):
```javascript
assert.deepStrictEqual(new Number(1), new Number(2)); // throws AssertionError
```

Closes #24045

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-11-30 16:58:58 -08:00
Dylan Conway
cc3fc5a1d3 fix ENG-24015 (#25222)
### What does this PR do?
Ensures `ptr` is either a number or heap big int before converting to a
number.

also fixes ENG-24039
### How did you verify your code works?
Added a test
2025-11-29 19:13:32 -08:00
Dylan Conway
d83e0eb1f1 fix ENG-24017 (#25224)
### What does this PR do?
Fixes checking for exceptions when creating empty or used readable
streams

also fixes ENG-24038
### How did you verify your code works?
Added a test for creating empty streams
2025-11-29 19:13:06 -08:00
Dylan Conway
72b9525507 update bunfig telemetry docs (#25237)
### What does this PR do?

### How did you verify your code works?
2025-11-29 19:12:18 -08:00
robobun
0f7494569e fix(console): implement %j format specifier for JSON output (#25195)
## Summary
- Implements the `%j` format specifier for `console.log` and related
console methods
- `%j` outputs the JSON stringified representation of the value
- Previously, `%j` was not recognized and was left as literal text in
the output

## Test plan
- [x] Run `bun bd test test/regression/issue/24234.test.ts` - all 5
tests pass
- [x] Verify tests fail with system Bun (`USE_SYSTEM_BUN=1`) to confirm
fix validity
- [x] Manual verification: `console.log('%j', {foo: 'bar'})` outputs
`{"foo":"bar"}`

## Example

Before (bug):
```
$ bun -e "console.log('%j %s', {foo: 'bar'}, 'hello')"
%j [object Object] hello
```

After (fixed):
```
$ bun -e "console.log('%j %s', {foo: 'bar'}, 'hello')"
{"foo":"bar"} hello
```

Closes #24234

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-28 22:57:55 -08:00
Meghan Denny
9fd6b54c10 ci: fix windows git dependencies tests (#25213) 2025-11-28 22:56:54 -08:00
robobun
19acc4dcac fix(buffer): handle string allocation failures in encoding operations (#25214)
## Summary
- Add proper bounds checking for encoding operations that produce larger
output than input
- Handle allocation failures gracefully by returning appropriate errors
- Add defensive checks in string initialization functions

## Test plan
- Added test case for encoding operations with large buffers
- Verified existing buffer tests still pass

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-28 22:56:28 -08:00
Meghan Denny
56da7c4fd9 zig: address a VM todo (#23678) 2025-11-28 19:38:26 -08:00
Meghan Denny
5bdb8ec0cb all: update to debian 13 (#24055) [publish images] 2025-11-28 15:01:40 -08:00
Meghan Denny
4cf9b794c9 ci: update buildkite agent to v3.114.0 (#25127) [publish images] 2025-11-28 15:01:20 -08:00
Meghan Denny
998ec54da9 test: fix spacing in sql.test.ts (#24691) 2025-11-28 14:40:58 -08:00
Jarred Sumner
0305f3d4d2 feat(url): implement URLPattern API (#25168)
## Summary

Implements the [URLPattern Web
API](https://developer.mozilla.org/en-US/docs/Web/API/URLPattern) based
on WebKit's implementation. URLPattern provides declarative pattern
matching for URLs, similar to how regular expressions work for strings.

### Features

- **Constructor**: Create patterns from strings or `URLPatternInit`
dictionaries
- **`test()`**: Check if a URL matches the pattern (returns boolean)
- **`exec()`**: Extract matched groups from a URL (returns
`URLPatternResult` or null)
- **Pattern properties**: `protocol`, `username`, `password`,
`hostname`, `port`, `pathname`, `search`, `hash`
- **`hasRegExpGroups`**: Detect if the pattern uses custom regular
expressions

### Example Usage

```js
// Match URLs with a user ID parameter
const pattern = new URLPattern({ pathname: '/users/:id' });

pattern.test('https://example.com/users/123'); // true
pattern.test('https://example.com/posts/456'); // false

const result = pattern.exec('https://example.com/users/123');
console.log(result.pathname.groups.id); // "123"

// Wildcard matching
const filesPattern = new URLPattern({ pathname: '/files/*' });
const match = filesPattern.exec('https://example.com/files/image.png');
console.log(match.pathname.groups[0]); // "image.png"
```

## Implementation Notes

- Adapted from WebKit's URLPattern implementation
- Modified JS bindings to work with Bun's infrastructure (simpler
`convertDictionary` patterns, WTF::Variant handling)
- Added IsoSubspaces for proper GC integration

## Test Plan

- [x] 408 tests from Web Platform Tests pass
- [x] Tests fail with system Bun (URLPattern not defined), pass with
debug build
- [x] Manual testing of basic functionality

Fixes https://github.com/oven-sh/bun/issues/2286

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-11-28 00:04:30 -08:00
Henrique Fonseca
1006a4fac2 Fix incorrect file name in React component test example 🌟 (#25167)
# What does this PR do?

Nyaa~ This PR fixes a small mistake in the documentation where the code
block for a React component test example was using the wrong filename!
(;ω;)💦

It was previously labeled as `matchers.d.ts`, but it should be something
like `myComponent.test.tsx` to properly reflect a test file for a React
component using `@testing-library/react`. 🧁

This makes the example clearer and more accurate for developers using
Bun to test their React components~! 💻🌸💕

# How did you verify your code works?

It's just docs, one single line 🥺

Pwease review and merge it when you can, senpai~~! UwU 🌈🫧
2025-11-27 23:15:34 -08:00
Michael H
c7f7d9bb82 run fmt (#25148)
prettier released a new update which seems to have changed a few
logistics
2025-11-28 17:51:45 +11:00
robobun
37bce389a0 docs: document inlining process.env.* values in static HTML bundling (#25084)
## Summary

- Add documentation for the `env` option that inlines `process.env.*`
values in frontend code when bundling HTML files
- Document runtime configuration via `bunfig.toml` `[serve.static]`
section for `bun ./index.html`
- Document production build configuration via CLI (`--env=PUBLIC_*`) and
`Bun.build` API (`env: "PUBLIC_*"`)
- Explain prefix filtering to avoid exposing sensitive environment
variables

## Test plan

- [x] Verify documentation renders correctly in local preview
- [x] Cross-reference with existing `env` documentation in
bundler/index.mdx

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Michael H <git@riskymh.dev>
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-11-28 17:51:11 +11:00
robobun
bab583497c fix(cli): correct --dry-run help text for bun publish (#25137)
## Summary
- Fix `bun publish --help` showing incorrect `--dry-run` description
("Don't install anything" → "Perform a dry run without making changes")
- The `--dry-run` flag is in a shared params array used by multiple
commands, so the new generic message works for all of them

Fixes #24806

## Test plan
- [x] Verify `bun publish --help` shows "Perform a dry run without
making changes" for --dry-run
- [x] Regression test added that validates the correct help text is
shown
- [x] Test passes with debug build, fails with system bun (validating it
tests the right thing)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-11-27 18:12:07 -08:00
robobun
a83fceafc7 fix(http2): return server from setTimeout for method chaining (#25138)
## Summary
- Make `Http2Server.setTimeout()` and `Http2SecureServer.setTimeout()`
return `this` to enable method chaining
- Matches Node.js behavior where `server.setTimeout(1000).listen()`
works

Fixes #24924

## Test plan
- [x] Test that `Http2Server.setTimeout()` returns server instance
- [x] Test that `Http2SecureServer.setTimeout()` returns server instance
- [x] Test method chaining works (e.g.,
`server.setTimeout(1000).close()`)
- [x] Tests pass with debug build, fail with system bun

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-11-27 16:46:15 -08:00
robobun
ef8eef3df8 fix(http): stricter validation in chunked encoding parser (#25159)
## Summary
- Adds stricter validation for chunk boundaries in the HTTP chunked
transfer encoding parser
- Ensures conformance with RFC 9112 requirements for chunk formatting
- Adds additional test coverage for chunked encoding edge cases

## Test plan
- Added new tests in `test/js/bun/http/request-smuggling.test.ts`
- All existing HTTP tests pass
- `bun bd test test/js/bun/http/request-smuggling.test.ts` passes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-27 16:29:35 -08:00
robobun
69b571da41 Delete claude.yml workflow (#25157) 2025-11-27 12:26:50 -08:00
robobun
908ab9ce30 feat(fetch): add proxy object format with headers support (#25090)
## Summary

- Extends `fetch()` proxy option to accept an object format: `proxy: {
url: string, headers?: Headers }`
- Allows sending custom headers to the proxy server (useful for proxy
authentication, custom routing headers, etc.)
- Headers are sent in CONNECT requests (for HTTPS targets) and direct
proxy requests (for HTTP targets)
- User-provided `Proxy-Authorization` header overrides auto-generated
credentials from URL

## Usage

```typescript
// Old format (still works)
fetch(url, { proxy: "http://proxy.example.com:8080" });

// New object format with headers
fetch(url, {
  proxy: {
    url: "http://proxy.example.com:8080",
    headers: {
      "Proxy-Authorization": "Bearer token",
      "X-Custom-Proxy-Header": "value"
    }
  }
});
```

## Test plan

- [x] Test proxy object with url string works same as string proxy
- [x] Test proxy object with headers sends headers to proxy (HTTP
target)
- [x] Test proxy object with headers sends headers in CONNECT request
(HTTPS target)
- [x] Test proxy object with Headers instance
- [x] Test proxy object with empty headers
- [x] Test proxy object with undefined headers
- [x] Test user-provided Proxy-Authorization overrides URL credentials
- [x] All existing proxy tests pass (25 total)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-26 15:11:45 -08:00
robobun
43c46b1f77 fix(FormData): throw error instead of assertion failure on very large input (#25006)
## Summary

- Fix crash in `FormData.from()` when called with very large ArrayBuffer
input
- Add length check in C++ `toString` function against both Bun's
synthetic limit and WebKit's `String::MaxLength`
- For UTF-8 tagged strings, use simdutf to calculate actual UTF-16
length only when byte length exceeds the limit

## Root Cause

When `FormData.from()` was called with a very large ArrayBuffer (e.g.,
`new Uint32Array(913148244)` = ~3.6GB), the code would crash with:

```
ASSERTION FAILED: data.size() <= MaxLength
vendor/WebKit/Source/WTF/wtf/text/StringImpl.h(886)
```

The `toString()` function in `helpers.h` was only checking against
`Bun__stringSyntheticAllocationLimit` (which defaults to ~4GB), but not
against WebKit's `String::MaxLength` (INT32_MAX, ~2GB). When the input
exceeded `String::MaxLength`, `createWithoutCopying()` would fail with
an assertion.

## Changes

1. **helpers.h**: Added `|| str.len > WTF::String::MaxLength` checks to
all three code paths in `toString()`:
- UTF-8 tagged pointer path (with simdutf length calculation only when
needed)
   - External pointer path
   - Non-copying creation path

2. **url.zig**: Reverted the incorrect Zig-side check (UTF-8 byte length
!= UTF-16 character length)

## Test plan

- [x] Added test that verifies FormData.from with oversized input
doesn't crash
- [x] Verified original crash case now returns empty FormData instead of
crashing:
  ```js
  const v3 = new Uint32Array(913148244);
  FormData.from(v3); // No longer crashes
  ```

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-11-26 13:46:08 -08:00
robobun
a0c5f3dc69 fix(mmap): use coerceToInt64 for offset/size to prevent assertion failure (#25101)
## Summary

- Fix assertion failure in `Bun.mmap` when `offset` or `size` options
are non-numeric values
- Add validation to reject negative `offset`/`size` with clear error
messages

Minimal reproduction: `Bun.mmap("", { offset: null });`

## Root Cause

`Bun.mmap` was calling `toInt64()` directly on the `offset` and `size`
options without validating they are numbers first. `toInt64()` has an
assertion that the value must be a number or BigInt, which fails when
non-numeric values like `null` or functions are passed.

## Test plan

- [x] Added tests for negative offset/size rejection
- [x] Added tests for non-number inputs (null, undefined)
- [x] `bun bd test test/js/bun/util/mmap.test.js` passes

Closes ENG-22413

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-26 13:37:41 -08:00
robobun
5965ff18ea fix(test): fix assertion failure in expect.extend with non-JSFunction callables (#25099)
## Summary

- Fix debug assertion failure in `JSWrappingFunction` when
`expect.extend()` is called with objects containing non-`JSFunction`
callables
- The crash occurred because `jsCast<JSFunction*>` was used, which
asserts the value inherits from `JSFunction`, but callable class
constructors (like `Expect`) inherit from `InternalFunction` instead

## Changes

- Change `JSWrappingFunction` to store `JSObject*` instead of
`JSFunction*`
- Use `jsDynamicCast` instead of `jsCast` in `getWrappedFunction`
- Use `getObject()` instead of `jsCast` in `create()`

## Reproduction

```js
const jest = Bun.jest();
jest.expect.extend(jest);
```

Before fix (debug build):
```
ASSERTION FAILED: !from || from->JSCell::inherits(std::remove_pointer<To>::type::info())
JSCast.h(40) : To JSC::jsCast(From *) [To = JSC::JSFunction *, From = JSC::JSCell]
```

After fix: Properly throws `TypeError: expect.extend: 'jest' is not a
valid matcher`

## Test plan

- [x] Added regression test
`test/regression/issue/fuzzer-ENG-22942.test.ts`
- [x] Existing `expect-extend.test.js` tests pass (27 tests)
- [x] Build succeeds

Fixes ENG-22942

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-26 13:34:02 -08:00
robobun
44f2328111 fix(fs.access): handle Windows device paths correctly (#25023)
## Summary

Fixes #23292

`fs.access()` and `fs.accessSync()` threw EUNKNOWN (-134) when checking
named pipes on Windows (paths like `\.\pipe\name`), but Node.js worked
fine.

**Repro:**
```ts
// Server creates pipe at \.\pipe\bun-test
import net from 'net';
const server = net.createServer();
server.listen('\\.\pipe\bun-test');

// Client tries to check if pipe exists
import fs from 'fs';
fs.accessSync('\\.\pipe\bun-test', fs.constants.F_OK);
// Error: EUNKNOWN: unknown error, access '\.\pipe\bun-test'
```

## Root Cause

The `osPathKernel32` function normalizes paths before passing to Windows
APIs. The normalization logic treats a single `.` as a "current
directory" component and removes it, so `\.\pipe\name` incorrectly
became `\pipe\name` - an invalid path.

## Solution

Detect Windows device paths (starting with `\.\` or `\?\`) and skip
normalization for these special paths, preserving the device prefix.

## Test Plan

- [x] Added regression test `test/regression/issue/23292.test.ts`
- [x] Test fails with system bun (v1.3.3): 3 failures (EUNKNOWN)
- [x] Test passes with fix: 4 pass

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-11-26 00:07:51 -08:00
robobun
85e0a723f3 Add analytics tracking for CPU profiling and heap snapshots (#25053)
## Summary

- Add `cpu_profile` and `heap_snapshot` counters to `Analytics.Features`
- Export `heap_snapshot` to C++ as `Bun__Feature__heap_snapshot`
- Increment `cpu_profile` when `--cpu-prof` flag is used
- Increment `heap_snapshot` in all heap snapshot creation locations:
  - `Bun.generateHeapSnapshot()`
  - `bun:jsc` `generateHeapSnapshotForDebugging()`
  - `console.takeHeapSnapshot()`
  - Internal `JSC__JSGlobalObject__generateHeapSnapshot()`

## Test plan

- [x] Build succeeds
- [x] Heap snapshot generation works
- [x] CPU profiling works with `--cpu-prof`
- [x] Existing tests pass: `test/js/bun/util/v8-heap-snapshot.test.ts`
- [x] Existing tests pass: `test/cli/run/cpu-prof.test.ts`

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-26 00:02:43 -08:00
robobun
d50c5a385f Add analytics tracking for HTTP client proxy usage (#25056)
## Summary
- Added `http_client_proxy` counter to `analytics.Features` struct
- Incremented counter in `ProxyTunnel.onOpen()` when proxy tunnel
connection opens successfully

This allows tracking HTTP client proxy usage in analytics/crash reports
alongside other features like `fetch`, `WebSocket`, `http_server`, etc.

## Test plan
- [x] Build completes successfully (`bun bd`)
- [x] Existing proxy tests pass (`bun bd test
test/js/bun/http/proxy.test.ts`)
- [x] Counter is properly integrated into the analytics framework

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-26 00:02:26 -08:00
Jarred Sumner
bb7641b3b0 fix: use GC-safe operations when populating error stack traces (#25096)
## Summary
- Adds `FinalizerSafety` enum to control whether `functionName` uses
GC-safe operations when iterating over stack traces
- Uses the enum in `populateStackFrameMetadata` to choose between the
richer callee-based path vs the GC-safe path
- Updates call sites in `ZigException.cpp` and
`FormatStackTraceForJS.cpp`

Fixes https://github.com/oven-sh/bun/issues/25094
Fixes https://github.com/oven-sh/bun/issues/20399
Fixes https://github.com/oven-sh/bun/issues/22662

## Test plan
- [ ] Add regression test

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-25 23:55:41 -08:00
Meghan Denny
22f4dfae7c ci: fix release step
don't try to release freebsd yet
2025-11-25 22:27:02 -08:00
Meghan Denny
9fce97bac3 scripts: add freebsd support to bootstrap.sh (#24534) 2025-11-25 17:16:38 -08:00
Dylan Conway
2fb3aa8991 update minimumReleaseAge (#25057)
### What does this PR do?

### How did you verify your code works?
2025-11-25 11:06:24 -08:00
robobun
dc25d66b00 fix(Buffer): improve input validation in *Write methods (#25011)
## Summary
Improve bounds checking logic in Buffer.*Write methods (utf8Write,
base64urlWrite, etc.) to properly handle edge cases with non-numeric
offset and length arguments, matching Node.js behavior.

## Changes
- Handle non-numeric offset by converting to integer (treating invalid
values as 0)
- Clamp length to available buffer space instead of throwing
- Reorder operations to check buffer state after argument conversion

## Node.js Compatibility

This matches Node.js's C++ implementation in `node_buffer.cc`:

**Offset handling via `ParseArrayIndex`**
([node_buffer.cc:211-234](https://github.com/nodejs/node/blob/main/src/node_buffer.cc#L211-L234)):
```cpp
inline MUST_USE_RESULT Maybe<bool> ParseArrayIndex(Environment* env,
                                                   Local<Value> arg,
                                                   size_t def,
                                                   size_t* ret) {
  if (arg->IsUndefined()) {
    *ret = def;
    return Just(true);
  }

  int64_t tmp_i;
  if (!arg->IntegerValue(env->context()).To(&tmp_i))
    return Nothing<bool>();
  // ...
}
```
V8's `IntegerValue` converts non-numeric values (including NaN) to 0.

**Length clamping in `SlowWriteString`**
([node_buffer.cc:1498-1502](https://github.com/nodejs/node/blob/main/src/node_buffer.cc#L1498-L1502)):
```cpp
THROW_AND_RETURN_IF_OOB(ParseArrayIndex(env, args[2], 0, &offset));
THROW_AND_RETURN_IF_OOB(
    ParseArrayIndex(env, args[3], ts_obj_length - offset, &max_length));

max_length = std::min(ts_obj_length - offset, max_length);
```
Node.js clamps `max_length` to available buffer space rather than
throwing.

## Test plan
- Added regression tests for all `*Write` methods verifying proper
handling of edge cases
- Verified behavior matches Node.js
- All 447 buffer tests pass

fixes ENG-21985, fixes ENG-21863, fixes ENG-21751, fixes ENG-21984

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-24 23:34:36 -08:00
robobun
ae29340708 fix: prevent calling class constructors marked with call: false (#25047)
## Summary

Fixes a crash (ENG-22243) where calling class constructors marked with
`call: false` would create invalid instances instead of throwing an
error.

## Root Cause

When a class definition has `call: false` (like `Bun.RedisClient`), the
code generator was still allowing the constructor to be invoked without
`new`. This created invalid instances that caused a buffer overflow
during garbage collection.

## The Fix

Modified `src/codegen/generate-classes.ts` to properly check the `call`
property:
- When `call: false`: throws `TypeError: Class constructor X cannot be
invoked without 'new'`
- When `call: true`: behaves as before, allowing construction without
`new`

## Test Plan

- [x] Added regression test in `test/regression/issue/22243.test.ts`
- [x] Test fails with system bun (has the bug)
- [x] Test passes with fixed build
- [x] Verified `Bun.RedisClient()` now throws proper error
- [x] Verified `new Bun.RedisClient()` still works

## Before

```bash
$ bun -e "Bun.RedisClient()"
# Creates invalid instance, no error
```

## After

```bash
$ bun -e "Bun.RedisClient()"
TypeError: Class constructor RedisClient cannot be invoked without 'new'
```

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-24 23:34:16 -08:00
robobun
123ac9dc2d chore: disable comment-lint and labeled workflows (#25059)
## Summary
- Disable `comment-lint.yml` (C++ linter comment workflow)
- Disable `labeled.yml` (Issue/PR labeled automation workflow)

Workflows are disabled by renaming them to `.yml.disabled`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-24 21:15:57 -08:00
Marko Vejnovic
48617563b5 ENG-21534: Satisfy aikido (#24880)
### What does this PR do?

- Bumps some packages
- Does some _best practices_ in certain areas to minimize Aikido noise.

### How did you verify your code works?

CI.

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-11-24 20:16:03 -08:00
robobun
cc393e43f2 fix(test): use putDirectMayBeIndex in spyOn for indexed property keys (#25020)
## Summary
- Fix `spyOn` crash when using indexed property keys (e.g., `spyOn(arr,
0)`)

## Test plan
- [x] Added tests for `spyOn` with numeric indexed properties
- [x] Added tests for `spyOn` with string indexed properties (e.g.,
`"0"`)
- [x] All existing `spyOn` tests pass
- [x] Full `mock-fn.test.js` test suite passes

Fixes ENG-21973

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-24 19:27:33 -08:00
robobun
3f0681996f fix(indexOfLine): properly coerce non-number offset argument (#25021)
## Summary
- Fix assertion failure when `Bun.indexOfLine` is called with a
non-number offset argument
- Changed from `.to(u32)` to `.coerce(i32, globalThis)` for proper
JavaScript type coercion

## Test plan
- [x] Added regression test in `test/js/bun/util/index-of-line.test.ts`
- [x] `bun bd test test/js/bun/util/index-of-line.test.ts` passes

Closes ENG-21997

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-11-24 19:27:14 -08:00
robobun
e14d5593c5 fix(install): use >= instead of > for resolution bounds check (#25028)
## Summary

- Fix off-by-one error in `preprocessUpdateRequests` where the bounds
check used `>` instead of `>=` when validating package IDs from the
resolution buffer
- When `old_resolution == packages.len`, the check `> packages.len`
passes but `resolutions_of_yore[old_resolution]` is out of bounds since
valid indices are `0` to `packages.len-1`
- This causes an internal assertion failure during `bun install` with
update requests

## The Bug

```zig
// BEFORE (buggy) - at lockfile.zig:484 and :522
if (old_resolution > old.packages.len) continue;
const res = resolutions_of_yore[old_resolution];  // OOB when old_resolution == packages.len

// AFTER (fixed)
if (old_resolution >= old.packages.len) continue;
const res = resolutions_of_yore[old_resolution];  // Now safe
```

## Crash Report

From
[bun.report](https://bun.report/1.3.3/wi1274e01cAggkggB+rt/F+pvBiw3rDqul/Doyi4Emzi5Ewj44FuvbgjMog00yDCYKERNEL32.DLLut0LCSntdll.dll4zijBA0eNrzzCtJLcpLzFFILC5OLSrJzM9TSEvMzCktSgUAiSkKPg/view):

```
panic: Internal assertion failure
- lockfile.zig:523: preprocessUpdateRequests
- install_with_manager.zig:605: installWithManager
- updatePackageJSONAndInstall.zig:340
Features: extracted_packages, text_lockfile
```

## Test plan

- [x] `bun run zig:check` passes
- [ ] CI passes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-24 19:22:45 -08:00
taylor.fish
7335cb747b Fix conversions from JSValue to FFI pointer (#25045)
Fixes this issue, where two identical JS numbers could become two
different FFI pointers:

```c
// gcc -fpic -shared -o main.so
#include <stdio.h>

void* getPtr(void) {
    return (void*)123;
}

void printPtr(void* ptr) {
    printf("%zu\n", (size_t)ptr);
}
```

```js
import { dlopen, FFIType } from "bun:ffi";

const lib = dlopen("./main.so", {
  getPtr: { args: [], returns: FFIType.ptr },
  printPtr: { args: [FFIType.ptr], returns: FFIType.void },
});

const ptr = lib.symbols.getPtr();
console.log(`${typeof ptr} ${ptr}`);

const ptr2 = Number(String(ptr));
console.log(`${typeof ptr2} ${ptr2}`);

console.log(`pointers equal? ${ptr === ptr2}`);
lib.symbols.printPtr(ptr);
lib.symbols.printPtr(ptr2);
```

```console
$ bun main.js
number 123
number 123
pointers equal? true
123
18446744073709551615
```

Fixes #20072

(For internal tracking: fixes ENG-22327)
2025-11-24 17:34:39 -08:00
Marko Vejnovic
9c8575f975 bug(#19588): Fix undici bindings overflow (#25046)
### What does this PR do?

- Fixes an overflow that happened in the undici bindings generator.
- Establishes a pattern using `std::tuple` so this doesn't happen again.

Fixes:

-
https://bun-p9.sentry.io/issues/6597708115/?query=createUndiciInternalBinding&referrer=issue-stream
- https://github.com/oven-sh/bun/issues/19588

### How did you verify your code works?

CI.

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-11-24 17:31:11 -08:00
robobun
0da132ef6d fix(test): skip grpc-js resolver tests that use unavailable domain (#25039)
## Summary

- Skip 2 tests that use `grpctest.kleinsch.com` (domain no longer
exists)
- Fix flaky "should not keep repeating failed resolutions" test

These tests were originally skipped when added in #14286, but were
accidentally un-skipped in #20051. This restores them to match upstream
grpc-node.

## To re-enable these tests in the future

Bun could set up its own DNS TXT record at `*.bun.sh`. According to the
[gRPC A2
spec](https://github.com/grpc/proposal/blob/master/A2-service-configs-in-dns.md):

**DNS Setup needed:**
1. A record: `grpctest.bun.sh` → any valid IP (e.g., `127.0.0.1`)
2. TXT record: `_grpc_config.grpctest.bun.sh` with value:
   ```

grpc_config=[{"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"service":"MyService","method":"Foo"}],"waitForReady":true}]}}]
   ```

Then update the tests to use `grpctest.bun.sh` instead.

## Test plan

- [x] `bun bd test test/js/third_party/grpc-js/test-resolver.test.ts`
passes (20 pass, 3 skip, 1 todo, 0 fail)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-24 10:34:26 -08:00
Jarred Sumner
0d863ba237 Don't use globalThis.takeException when rejecting Promise values (#24986)
### What does this PR do?

We can't use globalThis.takeException() because it throws out of memory
error when we instead need to take the exception.

### How did you verify your code works?
2025-11-23 20:27:15 -08:00
Michael H
f31db64bd4 cross-platform bun bd (#24983)
closes #24969
2025-11-23 15:09:43 -08:00
robobun
ddcec61f59 fix: use >= instead of > for String.max_length() check (#24988)
## Summary

- Fixed boundary check in `String.zig` to use `>=` instead of `>` for
`max_length()` comparisons
- Strings fail when the length is exactly equal to `max_length()`, not
just when exceeding it
- This affects both `createExternal` and
`createExternalGloballyAllocated` functions

## Test plan

- Existing tests should continue to pass
- Strings with length exactly equal to `max_length()` will now be
properly rejected

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-23 01:42:32 -08:00
Dylan Conway
29051f9340 fix(Bun.plugin): return on invalid target error (#24945)
### What does this PR do?

### How did you verify your code works?

Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-11-23 01:41:42 -08:00
robobun
7076fbbe68 fix(glob): fix typo that caused patterns like .*/* to escape cwd boundary (#24939)
## Summary

- Fixed a typo in `makeComponent` that incorrectly identified
2-character patterns starting with `.` (like `.*`) as `..` (DotBack)
patterns
- The condition checked `pattern[component.start] == '.'` twice instead
of checking both characters at positions 0 and 1
- This caused patterns like `.*/*` to be parsed as `../` + `*`, making
the glob walker traverse into parent directories

Fixes #24936

## Test plan

- [x] Added tests in `test/js/bun/glob/scan.test.ts` that verify
patterns like `.*/*` and `.*/**/*.ts` don't escape the cwd boundary
- [x] Tests fail with system bun (bug reproduced) and pass with the fix
- [x] All existing glob tests pass (169 tests)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-11-23 01:41:17 -08:00
Marko Vejnovic
67be07fca4 Fix fuzzilli_command.zig (#24941)
### What does this PR do?

Needed to fix `fuzzilli_command.zig` to get it to build

### How did you verify your code works?
2025-11-23 00:34:27 -08:00
Dylan Conway
25b91e5c86 Update JSValue.toSliceClone to use JSError (#24949)
### What does this PR do?
Removes a TODO
### How did you verify your code works?

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-11-23 00:32:38 -08:00
Jarred Sumner
3c60fcda33 Fixes #24711 (#24982)
### What does this PR do?

Calling `.withAsyncContextIfNeeded` on a Promise is both unnecessary and
incorrect

### How did you verify your code works?
2025-11-22 23:50:34 -08:00
robobun
8da699681e test: add security scanner integration tests for minimum-release-age (#24944) 2025-11-22 15:08:12 -08:00
Alistair Smith
7a06dfcb89 fix: collect all dependencies from workspace packages in scanner (#24942)
### What does this PR do?

Fixes #23688

### How did you verify your code works?

Another test
2025-11-21 18:31:45 -08:00
Michael H
9ed53283a4 bump versions to v1.3.3 (#24933) 2025-11-21 14:22:28 -08:00
Michael H
4450d738fa docs: more consistency + minor updates (#24764)
Co-authored-by: RiskyMH <git@riskymh.dev>
2025-11-21 14:06:19 -08:00
robobun
7ec1aa8c95 docs: document new features from v1.3.2 and v1.3.3 (#24932)
## What does this PR do?

Adds missing documentation for features introduced in Bun v1.3.2 and
v1.3.3:

- **Standalone executable config flags**
(`docs/bundler/executables.mdx`): Document
`--no-compile-autoload-dotenv` and `--no-compile-autoload-bunfig` flags
that control automatic config file loading in compiled binaries
- **Test retry/repeats** (`docs/test/writing-tests.mdx`): Document the
`retry` and `repeats` test options for handling flaky tests
- **Disable env file loading**
(`docs/runtime/environment-variables.mdx`): Document `--no-env-file`
flag and `env = false` bunfig option

## How did you verify your code works?

- [x] Verified documentation is accurate against source code
implementation in `src/cli/Arguments.zig`
- [x] Verified features are not already documented elsewhere
- [x] Cross-referenced with v1.3.2 and v1.3.3 release notes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-21 12:45:57 -08:00
Marko Vejnovic
abb1b0c4d7 test(ENG-21524): Fuzzilli Stop-Gap (#24826)
### What does this PR do?

Adds [@mschwarzl's Fuzzilli Support
PR](https://github.com/oven-sh/bun/pull/23862) with the changes
necessary to be able to:

- Run it in CI
- Make no impact on `debug` and `release` mode.

### How did you verify your code works?

---------

Co-authored-by: Martin Schwarzl <mschwarzl@cloudflare.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Dylan Conway <dylan.conway567@gmail.com>
2025-11-20 23:37:31 -08:00
Dylan Conway
274e01c737 remove jsc.createCallback (#24910)
### What does this PR do?
This was creating `Zig::FFIFunction` when we could instead use a plain
`JSC::JSFunction`
### How did you verify your code works?
Added a test
2025-11-20 20:56:02 -08:00
Conner Phillippi
a0c5edb15b Add new package paths to .aikido configuration 2025-11-20 17:35:16 -08:00
Meghan Denny
5702b39ef1 runtime: implement CompressionStream/DecompressionStream (#24757)
Closes https://github.com/oven-sh/bun/issues/1723
Closes https://github.com/oven-sh/bun/pull/22214
Closes https://github.com/oven-sh/bun/pull/24241

also supports the `"brotli"` and `"zstd"` formats

<img width="1244" height="547" alt="image"
src="https://github.com/user-attachments/assets/aecf4489-29ad-411d-9f6b-3bee50ed1b27"
/>
2025-11-20 17:14:37 -08:00
Dylan Conway
b72ba31441 fix(Blob.prototype.stream): handle undefined chunkSize (#24900)
### What does this PR do?
`blob.stream(undefined)`
### How did you verify your code works?
Added a test

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-11-20 17:01:24 -08:00
Meghan Denny
b92d2edcff Rename test-http-chunked-encoding-must be-valid-after-without-flushHeaders.ts to test-http-chunked-encoding-must-be-valid-after-without-flushHeaders.ts 2025-11-20 15:36:31 -08:00
Meghan Denny
a4af0aa4a8 Rename test-http-should-not-emit-or-throw error-when-writing-after-socket.end.ts to test-http-should-not-emit-or-throw-error-when-writing-after-socket.end.ts 2025-11-20 15:36:02 -08:00
Conner Phillippi
28b950e2b0 Add 'bench' to excluded paths in .aikido (#24879)
### What does this PR do?

### How did you verify your code works?
2025-11-19 23:46:30 -08:00
Conner Phillippi
595ad7de93 Add .aikido configuration file to exclude test and scripts directories (#24877) 2025-11-19 23:37:55 -08:00
Alistair Smith
b38ba38a18 types: correct ReadableStream methods, allow Response instance for serve routes under a method (#24872) 2025-11-19 23:08:49 -08:00
Jarred Sumner
788f03454d Show debugger in crash reports (#24871)
### What does this PR do?

Show debugger in crash reports

### How did you verify your code works?
2025-11-19 22:52:01 -08:00
Dylan Conway
0e23375d20 fix ENG-21527 (#24861)
### What does this PR do?
fixes ENG-21527
### How did you verify your code works?
Added a test
2025-11-19 22:44:21 -08:00
Jarred Sumner
d584c86d5b Delete incorrect debug assertion 2025-11-19 22:16:41 -08:00
Dylan Conway
0480d55a67 fix(YAML): handle exponential merge keys (#24729)
### What does this PR do?
Fixes ENG-21490
### How did you verify your code works?
Added a test that would previously fail due to timeout. It also confirms
the parsed result is correct.

---------

Co-authored-by: taylor.fish <contact@taylor.fish>
2025-11-19 21:20:55 -08:00
Jarred Sumner
9189fc4fa1 Fixes #24817 (#24864)
### What does this PR do?

Fixes #24817

### How did you verify your code works?
Test

---------

Co-authored-by: taylor.fish <contact@taylor.fish>
2025-11-19 21:17:51 -08:00
Dylan Conway
b554626662 fix ENG-21528 (#24865)
### What does this PR do?
Makes sure we are creating error messages with an allocator that will
not `deinit` at the end of function scope on error.

fixes ENG-21528
### How did you verify your code works?
Added a test
2025-11-19 20:31:37 -08:00
Dylan Conway
0054506538 fix(windows): close worker libuv loop (#24811)
### What does this PR do?
We need to call `uv_loop_close` in order to remove the threadlocal loop
from a list in libuv so it won't be used later. This explains the crash
reports because they have `workers_terminated` in features.

Fixes #24804
Closes BUN-3NV
Closes ENG-21523
### How did you verify your code works?
Manually. I'm not sure how to write a test yet other than manually
clicking sleep

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Zack Radisic <zack@theradisic.com>
2025-11-19 18:54:41 -08:00
Meghan Denny
1b36d35253 cmake: separate variable for ZIG_COMPILER_SAFE default is unnecessary (#24797) 2025-11-18 17:51:19 -08:00
Ciro Spaciari
9a9473d4b9 fix(createEmptyObject) fix some createEmptyObject values part 2 (#24827)
### What does this PR do?
We must use the right number of properties or we should set it to 0

### How did you verify your code works?
Read the code to check the amount of properties + CI
2025-11-18 14:02:21 -08:00
Ciro Spaciari
2d954995cd Fix Response wrapper and us_internal_disable_sweep_timer (#24623)
### What does this PR do?
Fix Response wrapper and us_internal_disable_sweep_timer
Fixes
https://linear.app/oven/issue/ENG-21510/panic-attempt-to-use-null-value-in-responsezig
### How did you verify your code works?
CI
2025-11-18 14:00:53 -08:00
Meghan Denny
11b20aa508 runtime: fix small leak in Bun.listen (#24799)
pulled out of https://github.com/oven-sh/bun/pull/21663

Co-authored-by: Ciro Spaciari <ciro.spaciari@gmail.com>
2025-11-18 12:00:56 -08:00
Meghan Denny
cac8e62635 zig: switch exhaustively on os + arch more (#24796) 2025-11-18 10:49:21 -08:00
Meghan Denny
f03957474e runtime: fix small leak in Bun.spawn (#24798)
pulled out of https://github.com/oven-sh/bun/pull/21663
2025-11-18 09:57:19 -05:00
Meghan Denny
ab80bbe4c2 runtime: fix small leak in node:net.SocketAddress (#24800)
pulled out of https://github.com/oven-sh/bun/pull/21663
2025-11-18 09:55:45 -05:00
Meghan Denny
af498a0483 runtime: fix small leak in Blob deinit (#24802)
pulled out of https://github.com/oven-sh/bun/pull/21663
2025-11-18 09:55:15 -05:00
robobun
7c485177ee Add compile-time flags to control .env and bunfig.toml autoloading (#24790)
## Summary

This PR adds two new compile options to control whether standalone
executables autoload `.env` files and `bunfig.toml` configuration files.

## New Options

### JavaScript API
```js
await Bun.build({
  entrypoints: ["./entry.ts"],
  compile: {
    autoloadDotenv: false,  // Disable .env loading (default: true)
    autoloadBunfig: false,  // Disable bunfig.toml loading (default: true)
  }
});
```

### CLI Flags
```bash
bun build --compile --no-compile-autoload-dotenv entry.ts
bun build --compile --no-compile-autoload-bunfig entry.ts
bun build --compile --compile-autoload-dotenv entry.ts
bun build --compile --compile-autoload-bunfig entry.ts
```

## Implementation

The flags are stored in a new `Flags` packed struct in
`StandaloneModuleGraph`:
```zig
pub const Flags = packed struct(u32) {
    disable_default_env_files: bool = false,
    disable_autoload_bunfig: bool = false,
    _padding: u30 = 0,
};
```

These flags are:
1. Set during compilation from CLI args or JS API options
2. Serialized into the `StandaloneModuleGraph` embedded in the
executable
3. Read at runtime in `bootStandalone()` to conditionally load config
files

## Testing

Manually tested and verified:
-  Default behavior loads `.env` files
-  `--no-compile-autoload-dotenv` disables `.env` loading
-  `--compile-autoload-dotenv` explicitly enables `.env` loading
-  Default behavior loads `bunfig.toml` (verified with preload script)
-  `--no-compile-autoload-bunfig` disables `bunfig.toml` loading

Test cases added in `test/bundler/bundler_compile_autoload.test.ts`

## Files Changed

- `src/StandaloneModuleGraph.zig` - Added Flags struct, updated
encode/decode
- `src/bun.js.zig` - Checks flags in bootStandalone()
- `src/bun.js/api/JSBundler.zig` - Added autoload options to
CompileOptions
- `src/bundler/bundle_v2.zig` - Pass flags to toExecutable()
- `src/cli.zig` - Added flags to BundlerOptions
- `src/cli/Arguments.zig` - Added CLI argument parsing
- `src/cli/build_command.zig` - Pass flags from context
- `test/bundler/expectBundled.ts` - Support new compile options
- `test/bundler/bundler_compile_autoload.test.ts` - New test file

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-11-18 09:46:44 -05:00
Marko Vejnovic
9513c1d1d9 chore: HttpContext.h cleanup (#24730) 2025-11-17 13:36:03 -08:00
robobun
509a97a435 Add --no-env-file flag to disable automatic .env loading (#24767)
## Summary

Implements `--no-env-file` CLI flag and bunfig configuration options to
disable automatic `.env` file loading at runtime and in the bundler.

## Motivation

Users may want to disable automatic `.env` file loading for:
- Production environments where env vars are managed externally
- CI/CD pipelines where .env files should be ignored
- Testing scenarios where explicit env control is needed
- Security contexts where .env files should not be trusted

## Changes

### CLI Flag
- Added `--no-env-file` flag that disables loading of default .env files
- Still respects explicit `--env-file` arguments for intentional env
loading

### Bunfig Configuration
Added support for disabling .env loading via `bunfig.toml`:
- `env = false` - disables default .env file loading
- `env = null` - disables default .env file loading  
- `env.file = false` - disables default .env file loading
- `env.file = null` - disables default .env file loading

### Implementation
- Added `disable_default_env_files` field to `api.TransformOptions` with
serialization support
- Added `disable_default_env_files` field to `options.Env` struct
- Implemented `loadEnvConfig` in bunfig parser to handle env
configuration
- Wired up flag throughout runtime and bundler code paths
- Preserved package.json script runner behavior (always skips default
.env files)

## Tests

Added comprehensive test suite (`test/cli/run/no-envfile.test.ts`) with
9 tests covering:
- `--no-env-file` flag with `.env`, `.env.local`,
`.env.development.local`
- Bunfig configurations: `env = false`, `env.file = false`, `env = true`
- `--no-env-file` with `-e` eval flag
- `--no-env-file` combined with `--env-file` (explicit files still load)
- Production mode behavior

All tests pass with debug bun and fail with system bun (as expected).

## Example Usage

```bash
# Disable all default .env files
bun --no-env-file index.js

# Disable defaults but load explicit file
bun --no-env-file --env-file .env.production index.js

# Disable via bunfig.toml
cat > bunfig.toml << 'CONFIG'
env = false
CONFIG
bun index.js
```

## Files Changed
- `src/cli/Arguments.zig` - CLI flag parsing
- `src/api/schema.zig` - API schema field with encode/decode
- `src/options.zig` - Env struct field and wiring
- `src/bunfig.zig` - Config parsing with loadEnvConfig
- `src/transpiler.zig` - Runtime wiring
- `src/bun.js.zig` - Runtime wiring
- `src/cli/exec_command.zig` - Runtime wiring
- `src/cli/run_command.zig` - Preserved package.json script runner
behavior
- `test/cli/run/no-envfile.test.ts` - Comprehensive test suite

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-17 15:04:42 -05:00
Dylan Conway
983bb52df7 fix #24550 (#24726)
### What does this PR do?
Fixes a regression introduced in Bun v1.3.2 with #24283.

We are not able to skip `sharp` lifecycle scripts before v0.33.0 because
previous versions did not use optional dependencies with prebuilds.

Fixes #24550
Fixes ENG-21519
### How did you verify your code works?
Manually

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-11-17 15:04:20 -05:00
Meghan Denny
8b5b36ec7a runtime: fix n-api ThreadSafeFunction finalizer (#24771)
Closes https://github.com/oven-sh/bun/issues/24552
Closes https://github.com/oven-sh/bun/issues/24664
Closes https://github.com/oven-sh/bun/issues/24702
Closes https://github.com/oven-sh/bun/issues/24703
Closes https://github.com/oven-sh/bun/issues/24768
2025-11-17 11:23:13 -08:00
Michael H
87eca6bbc7 docs: re-apply many recent changes that somehow aren't present (#24719)
lots of recent changes aren't present, so this reapplies them
2025-11-16 19:23:01 +11:00
624 changed files with 29495 additions and 4404 deletions

19
.aikido Normal file
View File

@@ -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

View File

@@ -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,16 +125,13 @@ 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" },
{ os: "linux", arch: "x64", distro: "ubuntu", release: "24.04", tier: "latest" },
{ os: "linux", arch: "x64", baseline: true, distro: "ubuntu", release: "25.04", tier: "latest" },
{ os: "linux", arch: "x64", baseline: true, distro: "ubuntu", release: "24.04", tier: "latest" },
{ os: "linux", arch: "aarch64", abi: "musl", distro: "alpine", release: "3.22", tier: "latest" },
{ os: "linux", arch: "x64", abi: "musl", distro: "alpine", release: "3.22", tier: "latest" },
{ os: "linux", arch: "x64", abi: "musl", baseline: true, distro: "alpine", release: "3.22", tier: "latest" },
@@ -659,7 +657,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 +1070,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 +1104,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);

View File

@@ -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 }}

16
.vscode/settings.json vendored
View File

@@ -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,

View File

@@ -6,7 +6,7 @@ This is the Bun repository - an all-in-one JavaScript runtime & toolkit designed
- **Build Bun**: `bun bd`
- Creates a debug build at `./build/debug/bun-debug`
- **CRITICAL**: no need for a timeout, the build is really fast!
- **CRITICAL**: do not set a timeout when running `bun bd`
- **Run tests with your debug build**: `bun bd test <test-file>`
- **CRITICAL**: Never use `bun test` directly - it won't include your changes
- **Run any command with debug build**: `bun bd <command>`

View File

@@ -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_<scope>=1` will enable debug logging for the corresponding `Output.scoped(.<scope>, .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=<path-to-file>.log`. Debug logs are aggressively removed in release builds.
- Use debug logs. `BUN_DEBUG_<scope>=1` will enable debug logging for the corresponding `Output.scoped(.<scope>, .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=<path-to-file>.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

2
LATEST
View File

@@ -1 +1 @@
1.3.2
1.3.4

View File

@@ -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/runtime/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)

View File

@@ -1,5 +1,6 @@
{
"lockfileVersion": 1,
"configVersion": 0,
"workspaces": {
"": {
"name": "bench",

View File

@@ -1,5 +1,6 @@
{
"lockfileVersion": 1,
"configVersion": 0,
"workspaces": {
"": {
"name": "installbench",
@@ -12,7 +13,7 @@
"@trpc/server": "^11.0.0",
"drizzle-orm": "^0.41.0",
"esbuild": "^0.25.11",
"next": "^15.2.3",
"next": "15.5.7",
"next-auth": "5.0.0-beta.25",
"postgres": "^3.4.4",
"react": "^19.0.0",
@@ -175,23 +176,23 @@
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "3.1.2", "@jridgewell/sourcemap-codec": "1.5.5" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
"@next/env": ["@next/env@15.5.6", "", {}, "sha512-3qBGRW+sCGzgbpc5TS1a0p7eNxnOarGVQhZxfvTdnV0gFI61lX7QNtQ4V1TSREctXzYn5NetbUsLvyqwLFJM6Q=="],
"@next/env": ["@next/env@15.5.7", "", {}, "sha512-4h6Y2NyEkIEN7Z8YxkA27pq6zTkS09bUSYC0xjd0NpwFxjnIKeZEeH591o5WECSmjpUhLn3H2QLJcDye3Uzcvg=="],
"@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@15.5.6", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ES3nRz7N+L5Umz4KoGfZ4XX6gwHplwPhioVRc25+QNsDa7RtUF/z8wJcbuQ2Tffm5RZwuN2A063eapoJ1u4nPg=="],
"@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@15.5.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-IZwtxCEpI91HVU/rAUOOobWSZv4P2DeTtNaCdHqLcTJU4wdNXgAySvKa/qJCgR5m6KI8UsKDXtO2B31jcaw1Yw=="],
"@next/swc-darwin-x64": ["@next/swc-darwin-x64@15.5.6", "", { "os": "darwin", "cpu": "x64" }, "sha512-JIGcytAyk9LQp2/nuVZPAtj8uaJ/zZhsKOASTjxDug0SPU9LAM3wy6nPU735M1OqacR4U20LHVF5v5Wnl9ptTA=="],
"@next/swc-darwin-x64": ["@next/swc-darwin-x64@15.5.7", "", { "os": "darwin", "cpu": "x64" }, "sha512-UP6CaDBcqaCBuiq/gfCEJw7sPEoX1aIjZHnBWN9v9qYHQdMKvCKcAVs4OX1vIjeE+tC5EIuwDTVIoXpUes29lg=="],
"@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@15.5.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-qvz4SVKQ0P3/Im9zcS2RmfFL/UCQnsJKJwQSkissbngnB/12c6bZTCB0gHTexz1s6d/mD0+egPKXAIRFVS7hQg=="],
"@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@15.5.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-NCslw3GrNIw7OgmRBxHtdWFQYhexoUCq+0oS2ccjyYLtcn1SzGzeM54jpTFonIMUjNbHmpKpziXnpxhSWLcmBA=="],
"@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@15.5.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-FsbGVw3SJz1hZlvnWD+T6GFgV9/NYDeLTNQB2MXoPN5u9VA9OEDy6fJEfePfsUKAhJufFbZLgp0cPxMuV6SV0w=="],
"@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@15.5.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-nfymt+SE5cvtTrG9u1wdoxBr9bVB7mtKTcj0ltRn6gkP/2Nu1zM5ei8rwP9qKQP0Y//umK+TtkKgNtfboBxRrw=="],
"@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@15.5.6", "", { "os": "linux", "cpu": "x64" }, "sha512-3QnHGFWlnvAgyxFxt2Ny8PTpXtQD7kVEeaFat5oPAHHI192WKYB+VIKZijtHLGdBBvc16tiAkPTDmQNOQ0dyrA=="],
"@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@15.5.7", "", { "os": "linux", "cpu": "x64" }, "sha512-hvXcZvCaaEbCZcVzcY7E1uXN9xWZfFvkNHwbe/n4OkRhFWrs1J1QV+4U1BN06tXLdaS4DazEGXwgqnu/VMcmqw=="],
"@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@15.5.6", "", { "os": "linux", "cpu": "x64" }, "sha512-OsGX148sL+TqMK9YFaPFPoIaJKbFJJxFzkXZljIgA9hjMjdruKht6xDCEv1HLtlLNfkx3c5w2GLKhj7veBQizQ=="],
"@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@15.5.7", "", { "os": "linux", "cpu": "x64" }, "sha512-4IUO539b8FmF0odY6/SqANJdgwn1xs1GkPO5doZugwZ3ETF6JUdckk7RGmsfSf7ws8Qb2YB5It33mvNL/0acqA=="],
"@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@15.5.6", "", { "os": "win32", "cpu": "arm64" }, "sha512-ONOMrqWxdzXDJNh2n60H6gGyKed42Ieu6UTVPZteXpuKbLZTH4G4eBMsr5qWgOBA+s7F+uB4OJbZnrkEDnZ5Fg=="],
"@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@15.5.7", "", { "os": "win32", "cpu": "arm64" }, "sha512-CpJVTkYI3ZajQkC5vajM7/ApKJUOlm6uP4BknM3XKvJ7VXAvCqSjSLmM0LKdYzn6nBJVSjdclx8nYJSa3xlTgQ=="],
"@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@15.5.6", "", { "os": "win32", "cpu": "x64" }, "sha512-pxK4VIjFRx1MY92UycLOOw7dTdvccWsNETQ0kDHkBlcFH1GrTLUjSiHU1ohrznnux6TqRHgv5oflhfIWZwVROQ=="],
"@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@15.5.7", "", { "os": "win32", "cpu": "x64" }, "sha512-gMzgBX164I6DN+9/PGA+9dQiwmTkE4TloBNx8Kv9UiGARsr9Nba7IpcBRA1iTV9vwlYnrE3Uy6I7Aj6qLjQuqw=="],
"@panva/hkdf": ["@panva/hkdf@1.2.1", "", {}, "sha512-6oclG6Y3PiDFcoyk8srjLfVKyMfVCKJ27JwNPViuXziFpmdz+MZnZN/aKY0JGXgYuO/VghU0jcOAZgWXZ1Dmrw=="],
@@ -323,7 +324,7 @@
"nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
"next": ["next@15.5.6", "", { "dependencies": { "@next/env": "15.5.6", "@swc/helpers": "0.5.15", "caniuse-lite": "1.0.30001752", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "15.5.6", "@next/swc-darwin-x64": "15.5.6", "@next/swc-linux-arm64-gnu": "15.5.6", "@next/swc-linux-arm64-musl": "15.5.6", "@next/swc-linux-x64-gnu": "15.5.6", "@next/swc-linux-x64-musl": "15.5.6", "@next/swc-win32-arm64-msvc": "15.5.6", "@next/swc-win32-x64-msvc": "15.5.6", "sharp": "0.34.4" }, "peerDependencies": { "react": "19.2.0", "react-dom": "19.2.0" }, "bin": { "next": "dist/bin/next" } }, "sha512-zTxsnI3LQo3c9HSdSf91O1jMNsEzIXDShXd4wVdg9y5shwLqBXi4ZtUUJyB86KGVSJLZx0PFONvO54aheGX8QQ=="],
"next": ["next@15.5.7", "", { "dependencies": { "@next/env": "15.5.7", "@swc/helpers": "0.5.15", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "15.5.7", "@next/swc-darwin-x64": "15.5.7", "@next/swc-linux-arm64-gnu": "15.5.7", "@next/swc-linux-arm64-musl": "15.5.7", "@next/swc-linux-x64-gnu": "15.5.7", "@next/swc-linux-x64-musl": "15.5.7", "@next/swc-win32-arm64-msvc": "15.5.7", "@next/swc-win32-x64-msvc": "15.5.7", "sharp": "^0.34.3" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-+t2/0jIJ48kUpGKkdlhgkv+zPTEOoXyr60qXe68eB/pl3CMJaLeIGjzp5D6Oqt25hCBiBTt8wEeeAzfJvUKnPQ=="],
"next-auth": ["next-auth@5.0.0-beta.25", "", { "dependencies": { "@auth/core": "0.37.2" }, "peerDependencies": { "next": "15.5.6", "react": "19.2.0" } }, "sha512-2dJJw1sHQl2qxCrRk+KTQbeH+izFbGFPuJj5eGgBZFYyiYYtvlrBeUw1E/OJJxTRjuxbSYGnCTkUIRsIIW0bog=="],

View File

@@ -26,7 +26,7 @@
"@trpc/server": "^11.0.0",
"drizzle-orm": "^0.41.0",
"esbuild": "^0.25.11",
"next": "^15.2.3",
"next": "15.5.7",
"next-auth": "5.0.0-beta.25",
"postgres": "^3.4.4",
"react": "^19.0.0",

View File

@@ -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;

View File

@@ -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();

View File

@@ -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();

View File

@@ -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,
};
@@ -603,15 +607,22 @@ fn configureObj(b: *Build, opts: *BunBuildOptions, obj: *Compile) void {
obj.llvm_codegen_threads = opts.llvm_codegen_threads orelse 0;
}
obj.no_link_obj = opts.os != .windows;
obj.no_link_obj = opts.os != .windows and !opts.no_llvm;
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;

View File

@@ -1,6 +1,6 @@
{
"lockfileVersion": 1,
"configVersion": 0,
"configVersion": 1,
"workspaces": {
"": {
"name": "bun",
@@ -36,6 +36,7 @@
},
"overrides": {
"@types/bun": "workspace:packages/@types/bun",
"@types/node": "25.0.0",
"bun-types": "workspace:packages/bun-types",
},
"packages": {
@@ -85,13 +86,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 +146,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 +156,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@25.0.0", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-rl78HwuZlaDIUSeUKkmogkhebA+8K1Hy7tddZuJ3D0xV8pZSfsYGTsliGUol1JPzu9EKnTxPC4L1fiWouStRew=="],
"aggregate-error": ["aggregate-error@3.1.0", "", { "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" } }, "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA=="],
@@ -187,7 +188,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 +212,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 +290,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 +306,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=="],

View File

@@ -10,4 +10,4 @@ preload = "./test/preload.ts"
[install]
linker = "isolated"
minimumReleaseAge = 1
minimumReleaseAge = 259200 # three days

View File

@@ -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(

View File

@@ -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()

View File

@@ -695,6 +695,7 @@ register_command(
-Dcpu=${ZIG_CPU}
-Denable_logs=$<IF:$<BOOL:${ENABLE_LOGS}>,true,false>
-Denable_asan=$<IF:$<BOOL:${ENABLE_ZIG_ASAN}>,true,false>
-Denable_fuzzilli=$<IF:$<BOOL:${ENABLE_FUZZILLI}>,true,false>
-Denable_valgrind=$<IF:$<BOOL:${ENABLE_VALGRIND}>,true,false>
-Duse_mimalloc=$<IF:$<BOOL:${USE_MIMALLOC_AS_DEFAULT_ALLOCATOR}>,true,false>
-Dllvm_codegen_threads=${LLVM_ZIG_CODEGEN_THREADS}

View File

@@ -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})

View File

@@ -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

View File

@@ -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

View File

@@ -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
@@ -71,6 +71,7 @@ ENV PATH "${PATH}:/usr/local/bun-node-fallback-bin"
# Temporarily use the `build`-stage image binaries to create a symlink:
RUN --mount=type=bind,from=build,source=/usr/bin,target=/usr/bin \
--mount=type=bind,from=build,source=/etc/alternatives/which,target=/etc/alternatives/which \
--mount=type=bind,from=build,source=/bin,target=/bin \
--mount=type=bind,from=build,source=/usr/lib,target=/usr/lib \
--mount=type=bind,from=build,source=/lib,target=/lib \

View File

@@ -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;

View File

@@ -65,6 +65,7 @@ In Bun's CLI, simple boolean flags like `--minify` do not accept an argument. Ot
| `--chunk-names` | `--chunk-naming` | Renamed for consistency with naming in JS API |
| `--color` | n/a | Always enabled |
| `--drop` | `--drop` | |
| n/a | `--feature` | Bun-specific. Enable feature flags for compile-time dead-code elimination via `import { feature } from "bun:bundle"` |
| `--entry-names` | `--entry-naming` | Renamed for consistency with naming in JS API |
| `--global-name` | n/a | Not applicable, Bun does not support `iife` output at this time |
| `--ignore-annotations` | `--ignore-dce-annotations` | |

View File

@@ -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
<Note>
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).
</Note>
---
@@ -183,6 +183,68 @@ console.log(process.execArgv); // ["--smol", "--user-agent=MyBot"]
---
## Automatic config loading
Standalone executables can automatically load configuration files from the directory where they are run. By default:
- **`tsconfig.json`** and **`package.json`** loading is **disabled** — these are typically only needed at development time, and the bundler already uses them when compiling
- **`.env`** and **`bunfig.toml`** loading is **enabled** — these often contain runtime configuration that may vary per deployment
<Note>
In a future version of Bun, `.env` and `bunfig.toml` may also be disabled by default for more deterministic behavior.
</Note>
### Enabling config loading at runtime
If your executable needs to read `tsconfig.json` or `package.json` at runtime, you can opt in with the new CLI flags:
```bash icon="terminal" terminal
# Enable runtime loading of tsconfig.json
bun build --compile --compile-autoload-tsconfig ./app.ts --outfile myapp
# Enable runtime loading of package.json
bun build --compile --compile-autoload-package-json ./app.ts --outfile myapp
# Enable both
bun build --compile --compile-autoload-tsconfig --compile-autoload-package-json ./app.ts --outfile myapp
```
### Disabling config loading at runtime
To disable `.env` or `bunfig.toml` loading for deterministic execution:
```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 all config loading
bun build --compile --no-compile-autoload-dotenv --no-compile-autoload-bunfig ./app.ts --outfile myapp
```
### JavaScript API
You can also configure autoloading via the JavaScript API:
```ts
await Bun.build({
entrypoints: ["./app.ts"],
compile: {
// tsconfig.json and package.json are disabled by default
autoloadTsconfig: true, // Enable tsconfig.json loading
autoloadPackageJson: true, // Enable package.json loading
// .env and bunfig.toml are enabled by default
autoloadDotenv: false, // Disable .env loading
autoloadBunfig: false, // Disable bunfig.toml loading
},
});
```
---
## Act as the Bun CLI
<Note>New in Bun v1.2.16</Note>
@@ -259,12 +321,12 @@ console.log(`Server running at http://localhost:${server.port}`);
</head>
<body>
<h1>Hello World</h1>
<script src="./app.js"></script>
<script src="./app.ts"></script>
</body>
</html>
```
```ts app.js icon="file-code"
```ts app.ts icon="file-code"
console.log("Hello from the client!");
```
@@ -351,39 +413,148 @@ cd /home/me/Desktop
## Embed assets & files
Standalone executables support embedding files.
Standalone executables support embedding files directly into the binary. This lets you ship a single executable that contains images, JSON configs, templates, or any other assets your application needs.
To embed files into an executable with `bun build --compile`, import the file in your code.
### How it works
Use the `with { type: "file" }` [import attribute](https://github.com/tc39/proposal-import-attributes) to embed a file:
```ts index.ts icon="/icons/typescript.svg"
import icon from "./icon.png" with { type: "file" };
console.log(icon);
// During development: "./icon.png"
// After compilation: "$bunfs/icon-a1b2c3d4.png" (internal path)
```
The import returns a **path string** that points to the embedded file. At build time, Bun:
1. Reads the file contents
2. Embeds the data into the executable
3. Replaces the import with an internal path (prefixed with `$bunfs/`)
You can then read this embedded file using `Bun.file()` or Node.js `fs` APIs.
### Reading embedded files with Bun.file()
`Bun.file()` is the recommended way to read embedded files:
```ts index.ts icon="/icons/typescript.svg"
// this becomes an internal file path
import icon from "./icon.png" with { type: "file" };
import { file } from "bun";
// Get file contents as different types
const bytes = await file(icon).arrayBuffer(); // ArrayBuffer
const text = await file(icon).text(); // string (for text files)
const blob = file(icon); // Blob
// Stream the file in a response
export default {
fetch(req) {
// Embedded files can be streamed from Response objects
return new Response(file(icon));
return new Response(file(icon), {
headers: { "Content-Type": "image/png" },
});
},
};
```
Embedded files can be read using `Bun.file`'s functions or the Node.js `fs.readFile` function (in `"node:fs"`).
### Reading embedded files with Node.js fs
For example, to read the contents of the embedded file:
Embedded files work seamlessly with Node.js file system APIs:
```ts index.ts icon="/icons/typescript.svg"
import icon from "./icon.png" with { type: "file" };
import config from "./config.json" with { type: "file" };
import { readFileSync, promises as fs } from "node:fs";
// Synchronous read
const iconBuffer = readFileSync(icon);
// Async read
const configData = await fs.readFile(config, "utf-8");
const parsed = JSON.parse(configData);
// Check file stats
const stats = await fs.stat(icon);
console.log(`Icon size: ${stats.size} bytes`);
```
### Practical examples
#### Embedding a JSON config file
```ts index.ts icon="/icons/typescript.svg"
import configPath from "./default-config.json" with { type: "file" };
import { file } from "bun";
const bytes = await file(icon).arrayBuffer();
// await fs.promises.readFile(icon)
// fs.readFileSync(icon)
// Load the embedded default configuration
const defaultConfig = await file(configPath).json();
// Merge with user config if it exists
const userConfig = await file("./user-config.json")
.json()
.catch(() => ({}));
const config = { ...defaultConfig, ...userConfig };
```
#### Serving static assets in an HTTP server
Use `static` routes in `Bun.serve()` for efficient static file serving:
```ts server.ts icon="/icons/typescript.svg"
import favicon from "./favicon.ico" with { type: "file" };
import logo from "./logo.png" with { type: "file" };
import styles from "./styles.css" with { type: "file" };
import { file, serve } from "bun";
serve({
static: {
"/favicon.ico": file(favicon),
"/logo.png": file(logo),
"/styles.css": file(styles),
},
fetch(req) {
return new Response("Not found", { status: 404 });
},
});
```
Bun automatically handles Content-Type headers and caching for static routes.
#### Embedding templates
```ts index.ts icon="/icons/typescript.svg"
import templatePath from "./email-template.html" with { type: "file" };
import { file } from "bun";
async function sendWelcomeEmail(user: { name: string; email: string }) {
const template = await file(templatePath).text();
const html = template.replace("{{name}}", user.name).replace("{{email}}", user.email);
// Send email with the rendered template...
}
```
#### Embedding binary files
```ts index.ts icon="/icons/typescript.svg"
import wasmPath from "./processor.wasm" with { type: "file" };
import fontPath from "./font.ttf" with { type: "file" };
import { file } from "bun";
// Load a WebAssembly module
const wasmBytes = await file(wasmPath).arrayBuffer();
const wasmModule = await WebAssembly.instantiate(wasmBytes);
// Read binary font data
const fontData = await file(fontPath).bytes();
```
### Embed SQLite databases
If your application wants to embed a SQLite database, set `type: "sqlite"` in the import attribute and the `embed` attribute to `"true"`.
If your application wants to embed a SQLite database into the compiled executable, set `type: "sqlite"` in the import attribute and the `embed` attribute to `"true"`.
The database file must already exist on disk. Then, import it in your code:
```ts index.ts icon="/icons/typescript.svg"
import myEmbeddedDb from "./my.db" with { type: "sqlite", embed: "true" };
@@ -391,7 +562,19 @@ import myEmbeddedDb from "./my.db" with { type: "sqlite", embed: "true" };
console.log(myEmbeddedDb.query("select * from users LIMIT 1").get());
```
This database is read-write, but all changes are lost when the executable exits (since it's stored in memory).
Finally, compile it into a standalone executable:
```bash terminal icon="terminal"
bun build --compile ./index.ts --outfile mycli
```
<Note>
The database file must exist on disk when you run `bun build --compile`. The `embed: "true"` attribute tells the
bundler to include the database contents inside the compiled executable. When running normally with `bun run`, the
database file is loaded from disk just like a regular SQLite import.
</Note>
In the compiled executable, the embedded database is read-write, but all changes are lost when the executable exits (since it's stored in memory).
### Embed N-API Addons
@@ -431,22 +614,57 @@ This is honestly a workaround, and we expect to improve this in the future with
### Listing embedded files
To get a list of all embedded files, use `Bun.embeddedFiles`:
`Bun.embeddedFiles` gives you access to all embedded files as `Blob` objects:
```ts index.ts icon="/icons/typescript.svg"
import "./icon.png" with { type: "file" };
import "./data.json" with { type: "file" };
import "./template.html" with { type: "file" };
import { embeddedFiles } from "bun";
console.log(embeddedFiles[0].name); // `icon-${hash}.png`
// List all embedded files
for (const blob of embeddedFiles) {
console.log(`${blob.name} - ${blob.size} bytes`);
}
// Output:
// icon-a1b2c3d4.png - 4096 bytes
// data-e5f6g7h8.json - 256 bytes
// template-i9j0k1l2.html - 1024 bytes
```
`Bun.embeddedFiles` returns an array of `Blob` objects which you can use to get the size, contents, and other properties of the files.
Each item in `Bun.embeddedFiles` is a `Blob` with a `name` property:
```ts
embeddedFiles: Blob[]
embeddedFiles: ReadonlyArray<Blob>;
```
The list of embedded files excludes bundled source code like `.ts` and `.js` files.
This is useful for dynamically serving all embedded assets using `static` routes:
```ts server.ts icon="/icons/typescript.svg"
import "./public/favicon.ico" with { type: "file" };
import "./public/logo.png" with { type: "file" };
import "./public/styles.css" with { type: "file" };
import { embeddedFiles, serve } from "bun";
// Build static routes from all embedded files
const staticRoutes: Record<string, Blob> = {};
for (const blob of embeddedFiles) {
// Remove hash from filename: "icon-a1b2c3d4.png" -> "icon.png"
const name = blob.name.replace(/-[a-f0-9]+\./, ".");
staticRoutes[`/${name}`] = blob;
}
serve({
static: staticRoutes,
fetch(req) {
return new Response("Not found", { status: 404 });
},
});
```
<Note>
`Bun.embeddedFiles` excludes bundled source code (`.ts`, `.js`, etc.) to help protect your application's source.
</Note>
#### Content hash
@@ -524,12 +742,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
```
<CodeGroup>
```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");
}
```
</CodeGroup>
```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.

View File

@@ -427,8 +427,8 @@ This will allow you to use TailwindCSS utility classes in your HTML and CSS file
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="tailwindcss" />
<!-- [!code ++] -->
<link rel="stylesheet" href="tailwindcss" />
</head>
<!-- the rest of your HTML... -->
</html>
@@ -448,8 +448,8 @@ Alternatively, you can import TailwindCSS in your CSS file:
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="./style.css" />
<!-- [!code ++] -->
<link rel="stylesheet" href="./style.css" />
</head>
<!-- the rest of your HTML... -->
</html>
@@ -492,6 +492,28 @@ Bun will lazily resolve and load each plugin and use them to bundle your routes.
the CLI.
</Note>
## 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)
```
<Note>
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.
</Note>
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 `<script>` and `<link>` tags in HTML files, uses them as entrypoints for Bun's bundler, generates an optimized bundle for the JavaScript/TypeScript/TSX/JSX and CSS files, and serves the result.
@@ -632,7 +654,7 @@ const server = serve({
console.log(`🚀 Server running on ${server.url}`);
```
```html title="public/index.html"
```html title="public/index.html" icon="file-code"
<!DOCTYPE html>
<html>
<head>
@@ -757,7 +779,7 @@ export function App() {
}
```
```css title="src/styles.css"
```css title="src/styles.css" icon="file-code"
* {
margin: 0;
padding: 0;
@@ -999,7 +1021,7 @@ CMD ["bun", "index.js"]
### Environment Variables
```bash title=".env.production" icon="file-code"
```ini title=".env.production" icon="file-code"
NODE_ENV=production
PORT=3000
DATABASE_URL=postgresql://user:pass@localhost:5432/myapp

View File

@@ -9,7 +9,7 @@ Hot Module Replacement (HMR) allows you to update modules in a running applicati
## `import.meta.hot` API Reference
Bun implements a client-side HMR API modeled after [Vite's `import.meta.hot` API](https://vitejs.dev/guide/api-hmr.html). It can be checked for with `if (import.meta.hot)`, tree-shaking it in production.
Bun implements a client-side HMR API modeled after [Vite's `import.meta.hot` API](https://vite.dev/guide/api-hmr). It can be checked for with `if (import.meta.hot)`, tree-shaking it in production.
```ts title="index.ts" icon="/icons/typescript.svg"
if (import.meta.hot) {
@@ -144,7 +144,7 @@ Indicates that multiple dependencies' modules can be accepted. This variant acce
`import.meta.hot.data` maintains state between module instances during hot replacement, enabling data transfer from previous to new versions. When `import.meta.hot.data` is written into, Bun will also mark this module as capable of self-accepting (equivalent of calling `import.meta.hot.accept()`).
```jsx title="index.ts" icon="/icons/typescript.svg"
```tsx title="index.tsx" icon="/icons/typescript.svg"
import { createRoot } from "react-dom/client";
import { App } from "./app";

View File

@@ -25,7 +25,7 @@ bun ./index.html
```
```
Bun v1.3.2
Bun v1.3.3
ready in 6.62ms
→ http://localhost:3000/
Press h + Enter to show shortcuts
@@ -51,7 +51,7 @@ bun index.html
```
```
Bun v1.3.2
Bun v1.3.3
ready in 6.62ms
→ http://localhost:3000/
Press h + Enter to show shortcuts
@@ -81,7 +81,7 @@ bun ./index.html ./about.html
```
```txt
Bun v1.3.2
Bun v1.3.3
ready in 6.62ms
→ http://localhost:3000/
Routes:
@@ -104,7 +104,7 @@ bun ./**/*.html
```
```
Bun v1.3.2
Bun v1.3.3
ready in 6.62ms
→ http://localhost:3000/
Routes:
@@ -122,7 +122,7 @@ bun ./index.html ./about/index.html ./about/foo/index.html
```
```
Bun v1.3.2
Bun v1.3.3
ready in 6.62ms
→ http://localhost:3000/
Routes:
@@ -164,7 +164,7 @@ For example:
}
```
```css abc.css
```css abc.css icon="file-code"
body {
background-color: red;
}
@@ -174,7 +174,7 @@ body {
This outputs:
```css
```css styles.css icon="file-code"
body {
background-color: red;
}
@@ -262,6 +262,93 @@ Then, reference TailwindCSS in your HTML via `<link>` tag, `@import` in CSS, or
<Info>Only one of those are necessary, not all three.</Info>
## Inline environment variables
Bun can replace `process.env.*` references in your JavaScript and TypeScript with their actual values at build time. This is useful for injecting configuration like API URLs or feature flags into your frontend code.
### Dev server (runtime)
To inline environment variables when using `bun ./index.html`, 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)
```
<Note>
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.
</Note>
Then run the dev server:
```bash terminal icon="terminal"
PUBLIC_API_URL=https://api.example.com bun ./index.html
```
### Build for production
When building static HTML for production, use the `env` option to inline environment variables:
<Tabs>
<Tab title="CLI">
```bash terminal icon="terminal"
# Inline all environment variables
bun build ./index.html --outdir=dist --env=inline
# Only inline env vars with a specific prefix (recommended)
bun build ./index.html --outdir=dist --env=PUBLIC_*
```
</Tab>
<Tab title="API">
```ts title="build.ts" icon="/icons/typescript.svg"
// Inline all environment variables
await Bun.build({
entrypoints: ["./index.html"],
outdir: "./dist",
env: "inline", // [!code highlight]
});
// Only inline env vars with a specific prefix (recommended)
await Bun.build({
entrypoints: ["./index.html"],
outdir: "./dist",
env: "PUBLIC_*", // [!code highlight]
});
```
</Tab>
</Tabs>
### Example
Given this source file:
```ts title="app.ts" icon="/icons/typescript.svg"
const apiUrl = process.env.PUBLIC_API_URL;
console.log(`API URL: ${apiUrl}`);
```
And running with `PUBLIC_API_URL=https://api.example.com`:
```bash terminal icon="terminal"
PUBLIC_API_URL=https://api.example.com bun build ./index.html --outdir=dist --env=PUBLIC_*
```
The bundled output will contain:
```js title="dist/app.js" icon="/icons/javascript.svg"
const apiUrl = "https://api.example.com";
console.log(`API URL: ${apiUrl}`);
```
## Echo console logs from browser to terminal
Bun's dev server supports streaming console logs from the browser to the terminal.
@@ -273,7 +360,7 @@ bun ./index.html --console
```
```
Bun v1.3.2
Bun v1.3.3
ready in 6.62ms
→ http://localhost:3000/
Press h + Enter to show shortcuts
@@ -385,7 +472,8 @@ All paths are resolved relative to your HTML file, making it easy to organize yo
- Need more configuration options for things like asset handling
- Need a way to configure CORS, headers, etc.
If you want to submit a PR, most of the code is [here](https://github.com/oven-sh/bun/blob/main/src/bun.js/api/bun/html-rewriter.ts). You could even copy paste that file into your project and use it as a starting point.
{/* todo: find the correct link to link to as this 404's and there isn't any similar files */}
{/* If you want to submit a PR, most of the code is [here](https://github.com/oven-sh/bun/blob/main/src/bun.js/api/bun/html-rewriter.ts). You could even copy paste that file into your project and use it as a starting point. */}
</Warning>

View File

@@ -106,7 +106,7 @@ For each file specified in `entrypoints`, Bun will generate a new bundle. This b
The contents of `out/index.js` will look something like this:
```ts title="out/index.js" icon="/icons/javascript.svg"
```js title="out/index.js" icon="/icons/javascript.svg"
// out/index.js
// ...
// ~20k lines of code
@@ -527,7 +527,7 @@ Injects environment variables into the bundled output by converting `process.env
For the input below:
```ts title="input.js" icon="/icons/javascript.svg"
```js title="input.js" icon="/icons/javascript.svg"
// input.js
console.log(process.env.FOO);
console.log(process.env.BAZ);
@@ -535,7 +535,7 @@ console.log(process.env.BAZ);
The generated bundle will contain the following code:
```ts title="output.js" icon="/icons/javascript.svg"
```js title="output.js" icon="/icons/javascript.svg"
// output.js
console.log("bar");
console.log("123");
@@ -580,7 +580,7 @@ console.log(process.env.BAZ);
The generated bundle will contain the following code:
```ts title="output.js" icon="/icons/javascript.svg"
```js title="output.js" icon="/icons/javascript.svg"
console.log(process.env.FOO);
console.log("https://acme.com");
console.log(process.env.BAZ);
@@ -722,7 +722,7 @@ Normally, bundling `index.tsx` would generate a bundle containing the entire sou
The generated bundle will look something like this:
```ts title="out/index.js" icon="/icons/javascript.svg"
```js title="out/index.js" icon="/icons/javascript.svg"
import { z } from "zod";
// ...
@@ -1026,7 +1026,7 @@ Setting `publicPath` will prefix all file paths with the specified value.
The output file would now look something like this.
```ts title="out/index.js" icon="/icons/javascript.svg"
```js title="out/index.js" icon="/icons/javascript.svg"
var logo = "https://cdn.example.com/logo-a7305bdef.svg";
```
@@ -1141,6 +1141,84 @@ Remove function calls from a bundle. For example, `--drop=console` will remove a
</Tab>
</Tabs>
### features
Enable compile-time feature flags for dead-code elimination. This provides a way to conditionally include or exclude code paths at bundle time using `import { feature } from "bun:bundle"`.
```ts title="app.ts" icon="/icons/typescript.svg"
import { feature } from "bun:bundle";
if (feature("PREMIUM")) {
// Only included when PREMIUM flag is enabled
initPremiumFeatures();
}
if (feature("DEBUG")) {
// Only included when DEBUG flag is enabled
console.log("Debug mode");
}
```
<Tabs>
<Tab title="JavaScript">
```ts title="build.ts" icon="/icons/typescript.svg"
await Bun.build({
entrypoints: ['./app.ts'],
outdir: './out',
features: ["PREMIUM"], // PREMIUM=true, DEBUG=false
})
```
</Tab>
<Tab title="CLI">
```bash terminal icon="terminal"
bun build ./app.ts --outdir ./out --feature PREMIUM
```
</Tab>
</Tabs>
The `feature()` function is replaced with `true` or `false` at bundle time. Combined with minification, unreachable code is eliminated:
```ts title="Input" icon="/icons/typescript.svg"
import { feature } from "bun:bundle";
const mode = feature("PREMIUM") ? "premium" : "free";
```
```js title="Output (with --feature PREMIUM --minify)" icon="/icons/javascript.svg"
var mode = "premium";
```
```js title="Output (without --feature PREMIUM, with --minify)" icon="/icons/javascript.svg"
var mode = "free";
```
**Key behaviors:**
- `feature()` requires a string literal argument — dynamic values are not supported
- The `bun:bundle` import is completely removed from the output
- Works with `bun build`, `bun run`, and `bun test`
- Multiple flags can be enabled: `--feature FLAG_A --feature FLAG_B`
- For type safety, augment the `Registry` interface to restrict `feature()` to known flags (see below)
**Use cases:**
- Platform-specific code (`feature("SERVER")` vs `feature("CLIENT")`)
- Environment-based features (`feature("DEVELOPMENT")`)
- Gradual feature rollouts
- A/B testing variants
- Paid tier features
**Type safety:** By default, `feature()` accepts any string. To get autocomplete and catch typos at compile time, create an `env.d.ts` file (or add to an existing `.d.ts`) and augment the `Registry` interface:
```ts title="env.d.ts" icon="/icons/typescript.svg"
declare module "bun:bundle" {
interface Registry {
features: "DEBUG" | "PREMIUM" | "BETA_FEATURES";
}
}
```
Ensure the file is included in your `tsconfig.json` (e.g., `"include": ["src", "env.d.ts"]`). Now `feature()` only accepts those flags, and invalid strings like `feature("TYPO")` become type errors.
## Outputs
The `Bun.build` function returns a `Promise<BuildOutput>`, defined as:
@@ -1356,10 +1434,12 @@ interface BuildConfig {
* JSX configuration object for controlling JSX transform behavior
*/
jsx?: {
runtime?: "automatic" | "classic";
importSource?: string;
factory?: string;
fragment?: string;
importSource?: string;
runtime?: "automatic" | "classic";
sideEffects?: boolean;
development?: boolean;
};
naming?:
| string
@@ -1376,7 +1456,7 @@ interface BuildConfig {
publicPath?: string;
define?: Record<string, string>;
loader?: { [k in string]: Loader };
sourcemap?: "none" | "linked" | "inline" | "external" | "linked" | boolean; // default: "none", true -> "inline"
sourcemap?: "none" | "linked" | "inline" | "external" | boolean; // default: "none", true -> "inline"
/**
* package.json `exports` conditions used when resolving imports
*
@@ -1443,13 +1523,20 @@ interface BuildConfig {
drop?: string[];
/**
* When set to `true`, the returned promise rejects with an AggregateError when a build failure happens.
* When set to `false`, the `success` property of the returned object will be `false` when a build failure happens.
* - When set to `true`, the returned promise rejects with an AggregateError when a build failure happens.
* - When set to `false`, returns a {@link BuildOutput} with `{success: false}`
*
* This defaults to `false` in Bun 1.1 and will change to `true` in Bun 1.2
* as most usage of `Bun.build` forgets to check for errors.
* @default true
*/
throw?: boolean;
/**
* Custom tsconfig.json file path to use for path resolution.
* Equivalent to `--tsconfig-override` in the CLI.
*/
tsconfig?: string;
outdir?: string;
}
interface BuildOutput {

View File

@@ -312,7 +312,7 @@ The `html` loader processes HTML files and bundles any referenced assets. It wil
For example, given this HTML file:
```html title="src/index.html"
```html title="src/index.html" icon="file-code"
<!DOCTYPE html>
<html>
<body>
@@ -325,7 +325,7 @@ For example, given this HTML file:
It will output a new HTML file with the bundled assets:
```html title="dist/index.html"
```html title="dist/index.html" icon="file-code"
<!DOCTYPE html>
<html>
<body>

View File

@@ -87,7 +87,7 @@ macro();
When shipping a library containing a macro to npm or another package registry, use the `"macro"` export condition to provide a special version of your package exclusively for the macro environment.
```json title="package.json" icon="file-code"
```json title="package.json" icon="file-json"
{
"name": "my-package",
"exports": {

View File

@@ -188,7 +188,7 @@
{
"group": "Publishing & Analysis",
"icon": "upload",
"pages": ["/pm/cli/publish", "/pm/cli/outdated", "/pm/cli/why", "/pm/cli/audit"]
"pages": ["/pm/cli/publish", "/pm/cli/outdated", "/pm/cli/why", "/pm/cli/audit", "/pm/cli/info"]
},
{
"group": "Workspace Management",
@@ -326,6 +326,7 @@
"group": "Utilities",
"icon": "wrench",
"pages": [
"/guides/util/upgrade",
"/guides/util/detect-bun",
"/guides/util/version",
"/guides/util/hash-a-password",
@@ -464,6 +465,7 @@
"/guides/test/update-snapshots",
"/guides/test/coverage",
"/guides/test/coverage-threshold",
"/guides/test/concurrent-test-glob",
"/guides/test/skip-tests",
"/guides/test/todo-tests",
"/guides/test/timeout",

View File

@@ -4,13 +4,9 @@ description: Share feedback, bug reports, and feature requests
mode: center
---
import Feedback from "/snippets/cli/feedback.mdx";
Whether you've found a bug, have a performance issue, or just want to suggest an improvement, here's how you can open a helpful issue:
<Callout icon="discord">
For general questions, please join our [Discord](https://discord.com/invite/CXdq2DP29u).
</Callout>
<Callout icon="discord">For general questions, please join our [Discord](https://bun.com/discord).</Callout>
## Reporting Issues
@@ -56,9 +52,7 @@ Whether you've found a bug, have a performance issue, or just want to suggest an
<Note>
- For MacOS and Linux: copy the output of `uname -mprs`
- For Windows: copy the output of this command in the powershell console:
```powershell
"$([Environment]::OSVersion | ForEach-Object VersionString) $(if ([Environment]::Is64BitOperatingSystem) { "x64" } else { "x86" })"
```
`"$([Environment]::OSVersion | ForEach-Object VersionString) $(if ([Environment]::Is64BitOperatingSystem) { "x64" } else { "x86" })"`
</Note>
</Step>
@@ -79,7 +73,3 @@ echo "please document X" | bun feedback --email you@example.com
```
You can provide feedback as text arguments, file paths, or piped input.
---
<Feedback />

View File

@@ -26,4 +26,4 @@ const regularArr = Array.from(uintArr);
---
See [Docs > API > Binary Data](https://bun.com/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.
See [Docs > API > Binary Data](/runtime/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -23,4 +23,4 @@ blob.type; // => "application/octet-stream"
---
See [Docs > API > Binary Data](https://bun.com/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.
See [Docs > API > Binary Data](/runtime/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -24,4 +24,4 @@ const nodeBuffer = Buffer.from(arrBuffer, 0, 16); // view first 16 bytes
---
See [Docs > API > Binary Data](https://bun.com/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.
See [Docs > API > Binary Data](/runtime/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -14,4 +14,4 @@ const str = decoder.decode(buf);
---
See [Docs > API > Binary Data](https://bun.com/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.
See [Docs > API > Binary Data](/runtime/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -38,4 +38,4 @@ const arr = new Uint8Array(buffer, 0, 16); // view first 16 bytes
---
See [Docs > API > Utils](https://bun.com/docs/api/utils) for more useful utilities.
See [Docs > API > Utils](/runtime/utils) for more useful utilities.

View File

@@ -13,4 +13,4 @@ const buf = await blob.arrayBuffer();
---
See [Docs > API > Binary Data](https://bun.com/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.
See [Docs > API > Binary Data](/runtime/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -13,4 +13,4 @@ const arr = new DataView(await blob.arrayBuffer());
---
See [Docs > API > Binary Data](https://bun.com/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.
See [Docs > API > Binary Data](/runtime/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -13,4 +13,4 @@ const stream = await blob.stream();
---
See [Docs > API > Binary Data](https://bun.com/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.
See [Docs > API > Binary Data](/runtime/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -14,4 +14,4 @@ const str = await blob.text();
---
See [Docs > API > Binary Data](https://bun.com/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.
See [Docs > API > Binary Data](/runtime/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -13,4 +13,4 @@ const arr = new Uint8Array(await blob.arrayBuffer());
---
See [Docs > API > Binary Data](https://bun.com/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.
See [Docs > API > Binary Data](/runtime/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -13,4 +13,4 @@ const arrBuf = nodeBuf.buffer;
---
See [Docs > API > Binary Data](https://bun.com/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.
See [Docs > API > Binary Data](/runtime/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -13,4 +13,4 @@ const blob = new Blob([buf]);
---
See [Docs > API > Binary Data](https://bun.com/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.
See [Docs > API > Binary Data](/runtime/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -40,4 +40,4 @@ const stream = blob.stream(1024);
---
See [Docs > API > Binary Data](https://bun.com/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.
See [Docs > API > Binary Data](/runtime/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -24,4 +24,4 @@ const str = buf.toString("utf8", 0, 5);
---
See [Docs > API > Binary Data](https://bun.com/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.
See [Docs > API > Binary Data](/runtime/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -13,4 +13,4 @@ buf instanceof Uint8Array; // => true
---
See [Docs > API > Binary Data](https://bun.com/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.
See [Docs > API > Binary Data](/runtime/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -14,4 +14,4 @@ const str = decoder.decode(dv);
---
See [Docs > API > Binary Data](https://bun.com/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.
See [Docs > API > Binary Data](/runtime/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -24,4 +24,4 @@ arr.byteLength; // => 32
---
See [Docs > API > Binary Data](https://bun.com/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.
See [Docs > API > Binary Data](/runtime/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -15,4 +15,4 @@ console.log(await blob.text());
---
See [Docs > API > Binary Data](https://bun.com/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.
See [Docs > API > Binary Data](/runtime/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -13,4 +13,4 @@ const buf = Buffer.from(arr);
---
See [Docs > API > Binary Data](https://bun.com/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.
See [Docs > API > Binary Data](/runtime/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -13,4 +13,4 @@ const dv = new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
---
See [Docs > API > Binary Data](https://bun.com/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.
See [Docs > API > Binary Data](/runtime/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -40,4 +40,4 @@ const stream = blob.stream(1024);
---
See [Docs > API > Binary Data](https://bun.com/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.
See [Docs > API > Binary Data](/runtime/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -15,4 +15,4 @@ const str = decoder.decode(arr);
---
See [Docs > API > Binary Data](https://bun.com/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun.
See [Docs > API > Binary Data](/runtime/binary-data#conversion) for complete documentation on manipulating binary data with Bun.

View File

@@ -4,8 +4,6 @@ sidebarTitle: Deploy on Vercel
mode: center
---
import { ProductCard } from "/snippets/product-card.mdx";
[Vercel](https://vercel.com/) is a cloud platform that lets you build, deploy, and scale your apps.
<Warning>
@@ -81,7 +79,7 @@ import { ProductCard } from "/snippets/product-card.mdx";
console.log("runtime", process.versions.bun);
```
```txt
runtime 1.3.2
runtime 1.3.3
```
[See the Vercel Bun Runtime documentation for feature support →](https://vercel.com/docs/functions/runtimes/bun#feature-support)

View File

@@ -22,7 +22,7 @@ bun add discord.js
---
Before we go further, we need to go to the [Discord developer portal](https://discord.com/developers/applications), login/signup, create a new _Application_, then create a new _Bot_ within that application. Follow the [official guide](https://discordjs.guide/preparations/setting-up-a-bot-application.html#creating-your-bot) for step-by-step instructions.
Before we go further, we need to go to the [Discord developer portal](https://discord.com/developers/applications), login/signup, create a new _Application_, then create a new _Bot_ within that application. Follow the [official guide](https://discordjs.guide/legacy/preparations/app-setup#creating-your-bot) for step-by-step instructions.
---
@@ -30,7 +30,7 @@ Once complete, you'll be presented with your bot's _private key_. Let's add this
<Note>This is an example token that has already been invalidated.</Note>
```txt .env.local icon="settings"
```ini .env.local icon="settings"
DISCORD_TOKEN=NzkyNzE1NDU0MTk2MDg4ODQy.X-hvzA.Ovy4MCQywSkoMRRclStW4xAYK7I
```

View File

@@ -7,8 +7,8 @@ mode: center
Express and other major Node.js HTTP libraries should work out of the box. Bun implements the [`node:http`](https://nodejs.org/api/http.html) and [`node:https`](https://nodejs.org/api/https.html) modules that these libraries rely on.
<Note>
Refer to the [Runtime > Node.js APIs](https://bun.com/docs/runtime/nodejs-apis#node-http) page for more detailed
compatibility information.
Refer to the [Runtime > Node.js APIs](/runtime/nodejs-compat#node-http) page for more detailed compatibility
information.
</Note>
```sh terminal icon="terminal"

View File

@@ -89,4 +89,4 @@ Moo!
---
This is a simple introduction to using Mongoose with TypeScript and Bun. As you build your application, refer to the official [MongoDB](https://docs.mongodb.com/) and [Mongoose](https://mongoosejs.com/docs/) sites for complete documentation.
This is a simple introduction to using Mongoose with TypeScript and Bun. As you build your application, refer to the official [MongoDB](https://www.mongodb.com/docs) and [Mongoose](https://mongoosejs.com/docs/) sites for complete documentation.

View File

@@ -20,7 +20,7 @@ bun add -D drizzle-kit
Create a `.env.local` file and add your [Neon Postgres connection string](https://neon.tech/docs/connect/connect-from-any-app) to it.
```txt .env.local icon="settings"
```ini .env.local icon="settings"
DATABASE_URL=postgresql://usertitle:password@ep-adj-noun-guid.us-east-1.aws.neon.tech/neondb?sslmode=require
```
@@ -33,7 +33,7 @@ import { neon } from "@neondatabase/serverless";
import { drizzle } from "drizzle-orm/neon-http";
// Bun automatically loads the DATABASE_URL from .env.local
// Refer to: https://bun.com/docs/runtime/env for more information
// Refer to: https://bun.com/docs/runtime/environment-variables for more information
const sql = neon(process.env.DATABASE_URL!);
export const db = drizzle(sql);

View File

@@ -21,7 +21,7 @@ bun add @neondatabase/serverless
Create a `.env.local` file and add your [Neon Postgres connection string](https://neon.tech/docs/connect/connect-from-any-app) to it.
```sh .env.local icon="settings"
```ini .env.local icon="settings"
DATABASE_URL=postgresql://usertitle:password@ep-adj-noun-guid.us-east-1.aws.neon.tech/neondb?sslmode=require
```
@@ -33,7 +33,7 @@ Paste the following code into your project's `index.ts` file.
import { neon } from "@neondatabase/serverless";
// Bun automatically loads the DATABASE_URL from .env.local
// Refer to: https://bun.com/docs/runtime/env for more information
// Refer to: https://bun.com/docs/runtime/environment-variables for more information
const sql = neon(process.env.DATABASE_URL);
const rows = await sql`SELECT version()`;

View File

@@ -14,7 +14,7 @@ bunx nuxi init my-nuxt-app
✔ Which package manager would you like to use?
bun
◐ Installing dependencies...
bun install v1.3.2 (16b4bf34)
bun install v1.3.3 (16b4bf34)
+ @nuxt/devtools@0.8.2
+ nuxt@3.7.0
785 packages installed [2.67s]
@@ -74,6 +74,12 @@ export default defineNuxtConfig({
});
```
Alternatively, you can set the preset via environment variable:
```sh terminal icon="terminal"
NITRO_PRESET=bun bun run build
```
<Note>
Some packages provide Bun-specific exports that Nitro will not bundle correctly using the default preset. In this
case, you need to use Bun preset so that the packages will work correctly in production builds.

View File

@@ -62,7 +62,7 @@ mode: center
<Step title="Configure database connection">
Set up your Postgres database URL in the `.env` file.
```env .env icon="settings"
```ini .env icon="settings"
DATABASE_URL="postgresql://username:password@localhost:5432/mydb?schema=public"
```
</Step>

View File

@@ -161,4 +161,4 @@ mode: center
---
That's it! Now that you've set up Prisma using Bun, we recommend referring to the [official Prisma docs](https://www.prisma.io/docs/concepts/components/prisma-client) as you continue to develop your application.
That's it! Now that you've set up Prisma using Bun, we recommend referring to the [official Prisma docs](https://www.prisma.io/docs/orm/prisma-client) as you continue to develop your application.

View File

@@ -65,14 +65,14 @@ bun create qwik
│ bun qwik add │
│ │
│ Relevant docs: │
│ https://qwik.builder.io/docs/getting-started/ │
│ https://qwik.dev/docs/getting-started/
│ │
│ Questions? Start the conversation at: │
│ https://qwik.builder.io/chat
│ https://qwik.dev/chat
│ https://twitter.com/QwikDev │
│ │
│ Presentations, Podcasts and Videos: │
│ https://qwik.builder.io/media/
│ https://qwik.dev/media/
│ │
│ Next steps: │
│ cd my-app │
@@ -111,4 +111,4 @@ Open [http://localhost:5173](http://localhost:5173) with your browser to see the
---
Refer to the [Qwik docs](https://qwik.builder.io/docs/getting-started/) for complete documentation.
Refer to the [Qwik docs](https://qwik.dev/docs/getting-started/) for complete documentation.

View File

@@ -20,7 +20,7 @@ bun add @sentry/bun
Then, initialize the Sentry SDK with your Sentry DSN in your app's entry file. You can find your DSN in your Sentry project settings.
```js sentry.ts icon="/icons/typescript.svg"
```ts sentry.ts icon="/icons/typescript.svg"
import * as Sentry from "@sentry/bun";
// Ensure to call this before importing any other modules!
@@ -37,7 +37,7 @@ Sentry.init({
You can verify that Sentry is working by capturing a test error:
```js sentry.ts icon="/icons/typescript.svg"
```ts sentry.ts icon="/icons/typescript.svg"
setTimeout(() => {
try {
foo();

View File

@@ -4,63 +4,59 @@ sidebarTitle: "SolidStart with Bun"
mode: center
---
<Warning>
SolidStart currently relies on Node.js APIs that Bun does not yet implement. The guide below uses Bun to initialize a
project and install dependencies, but it uses Node.js to run the dev server.
</Warning>
---
Initialize a SolidStart app with `create-solid`.
Initialize a SolidStart app with `create-solid`. You can specify the `--solidstart` flag to create a SolidStart project, and `--ts` for TypeScript support. When prompted for a template, select `basic` for a minimal starter app.
```sh terminal icon="terminal"
bun create solid my-app
bun create solid my-app --solidstart --ts
```
```txt
create-solid version 0.2.31
Welcome to the SolidStart setup wizard!
There are definitely bugs and some feature might not work yet.
If you encounter an issue, have a look at
https://github.com/solidjs/solid-start/issues and open a new one,
if it is not already tracked.
✔ Which template do you want to use? todomvc
✔ Server Side Rendering? … yes
✔ Use TypeScript? … yes
cloned solidjs/solid-start#main to /path/to/my-app/.solid-start
✔ Copied project files
Create-Solid v0.6.11
◇ Project Name
│ my-app
◇ Which template would you like to use?
│ basic
◇ Project created 🎉
◇ To get started, run: ─╮
│ │
│ cd my-app │
│ bun install │
│ bun dev │
│ │
├────────────────────────╯
```
---
As instructed by the `create-solid` CLI, let's install our dependencies.
As instructed by the `create-solid` CLI, install the dependencies.
```sh terminal icon="terminal"
cd my-app
bun install
```
---
Then run the development server.
Then run the development server with `bun dev`.
```sh terminal icon="terminal"
bun run dev
# or, equivalently
bunx solid-start dev
bun dev
```
---
```txt
$ vinxi dev
vinxi v0.5.8
vinxi starting dev server
➜ Local: http://localhost:3000/
➜ Network: use --host to expose
```
Open [localhost:3000](http://localhost:3000). Any changes you make to `src/routes/index.tsx` will be hot-reloaded automatically.
<Frame>
![SolidStart demo app](https://github.com/oven-sh/bun/assets/3084745/1e8043c4-49d1-498c-9add-c1eaab6c7167)
</Frame>
---
Refer to the [SolidStart website](https://start.solidjs.com/getting-started/what-is-solidstart) for complete framework documentation.
Refer to the [SolidStart website](https://docs.solidjs.com/solid-start) for complete framework documentation.

View File

@@ -88,7 +88,7 @@ To build for production, you'll need to add the right SvelteKit adapter. Current
Now, make the following changes to your `svelte.config.js`.
```ts svelte.config.js icon="file-code"
```js svelte.config.js icon="file-code"
import adapter from "@sveltejs/adapter-auto"; // [!code --]
import adapter from "svelte-adapter-bun"; // [!code ++]
import { vitePreprocess } from "@sveltejs/vite-plugin-svelte";

View File

@@ -98,7 +98,6 @@ To host your TanStack Start app, you can use [Nitro](https://nitro.build/) or a
}
```
<Note>
You do **not** need the custom `start` script when deploying to Vercel.
</Note>

View File

@@ -34,7 +34,7 @@ mode: center
Set the `REDIS_URL` environment variable in your `.env` file using the Redis endpoint (not the REST URL):
```env .env icon="settings"
```ini .env icon="settings"
REDIS_URL=rediss://********@********.upstash.io:6379
```

View File

@@ -74,4 +74,4 @@ bunx --bun vite build
---
This is a stripped down guide to get you started with Vite + Bun. For more information, see the [Vite documentation](https://vitejs.dev/guide/).
This is a stripped down guide to get you started with Vite + Bun. For more information, see the [Vite documentation](https://vite.dev/guide/).

View File

@@ -6,7 +6,7 @@ mode: center
## Extract links from a webpage
Bun's [HTMLRewriter](https://bun.com/docs/api/html-rewriter) API can be used to efficiently extract links from HTML content. It works by chaining together CSS selectors to match the elements, text, and attributes you want to process. This is a simple example of how to extract links from a webpage. You can pass `.transform` a `Response`, `Blob`, or `string`.
Bun's [HTMLRewriter](/runtime/html-rewriter) API can be used to efficiently extract links from HTML content. It works by chaining together CSS selectors to match the elements, text, and attributes you want to process. This is a simple example of how to extract links from a webpage. You can pass `.transform` a `Response`, `Blob`, or `string`.
```ts extract-links.ts icon="/icons/typescript.svg"
async function extractLinks(url: string) {
@@ -37,6 +37,7 @@ await extractLinks("https://bun.com");
When scraping websites, you often want to convert relative URLs (like `/docs`) to absolute URLs. Here's how to handle URL resolution:
{/* prettier-ignore */}
```ts extract-links.ts icon="/icons/typescript.svg"
async function extractLinksFromURL(url: string) {
const response = await fetch(url);
@@ -47,13 +48,11 @@ async function extractLinksFromURL(url: string) {
const href = el.getAttribute("href");
if (href) {
// Convert relative URLs to absolute // [!code ++]
try {
// [!code ++]
try { // [!code ++]
const absoluteURL = new URL(href, url).href; // [!code ++]
links.add(absoluteURL); // [!code ++]
} catch {
// [!code ++]
links.add(href);
links.add(absoluteURL);
} catch { // [!code ++]
links.add(href); // [!code ++]
} // [!code ++]
}
},
@@ -69,4 +68,4 @@ const websiteLinks = await extractLinksFromURL("https://example.com");
---
See [Docs > API > HTMLRewriter](https://bun.com/docs/api/html-rewriter) for complete documentation on HTML transformation with Bun.
See [Docs > API > HTMLRewriter](/runtime/html-rewriter) for complete documentation on HTML transformation with Bun.

View File

@@ -6,7 +6,7 @@ mode: center
## Extract social share images and Open Graph tags
Bun's [HTMLRewriter](https://bun.com/docs/api/html-rewriter) API can be used to efficiently extract social share images and Open Graph metadata from HTML content. This is particularly useful for building link preview features, social media cards, or web scrapers. We can use HTMLRewriter to match CSS selectors to HTML elements, text, and attributes we want to process.
Bun's [HTMLRewriter](/runtime/html-rewriter) API can be used to efficiently extract social share images and Open Graph metadata from HTML content. This is particularly useful for building link preview features, social media cards, or web scrapers. We can use HTMLRewriter to match CSS selectors to HTML elements, text, and attributes we want to process.
```ts extract-social-meta.ts icon="/icons/typescript.svg"
interface SocialMetadata {

View File

@@ -63,8 +63,9 @@ Our form will send a `POST` request to the `/action` endpoint with the form data
First we use the [`.formData()`](https://developer.mozilla.org/en-US/docs/Web/API/Request/formData) method on the incoming `Request` to asynchronously parse its contents to a `FormData` instance. Then we can use the [`.get()`](https://developer.mozilla.org/en-US/docs/Web/API/FormData/get) method to extract the value of the `name` and `profilePicture` fields. Here `name` corresponds to a `string` and `profilePicture` is a `Blob`.
Finally, we write the `Blob` to disk using [`Bun.write()`](https://bun.com/docs/api/file-io#writing-files-bun-write).
Finally, we write the `Blob` to disk using [`Bun.write()`](/runtime/file-io#writing-files-bun-write).
{/* prettier-ignore */}
```ts index.ts icon="/icons/typescript.svg"
const server = Bun.serve({
port: 4000,
@@ -80,8 +81,7 @@ const server = Bun.serve({
});
// parse formdata at /action // [!code ++]
if (url.pathname === "/action") {
// [!code ++]
if (url.pathname === "/action") { // [!code ++]
const formdata = await req.formData(); // [!code ++]
const name = formdata.get("name"); // [!code ++]
const profilePicture = formdata.get("profilePicture"); // [!code ++]

View File

@@ -4,7 +4,7 @@ sidebarTitle: Hot reload an HTTP server
mode: center
---
Bun supports the [`--hot`](https://bun.com/docs/runtime/hot#hot-mode) flag to run a file with hot reloading enabled. When any module or file changes, Bun re-runs the file.
Bun supports the [`--hot`](/runtime/watch-mode#hot-mode) flag to run a file with hot reloading enabled. When any module or file changes, Bun re-runs the file.
```sh terminal icon="terminal"
bun --hot run index.ts

View File

@@ -9,18 +9,42 @@ In Bun, `fetch` supports sending requests through an HTTP or HTTPS proxy. This i
```ts proxy.ts icon="/icons/typescript.svg"
await fetch("https://example.com", {
// The URL of the proxy server
proxy: "https://usertitle:password@proxy.example.com:8080",
proxy: "https://username:password@proxy.example.com:8080",
});
```
---
The `proxy` option is a URL string that specifies the proxy server. It can include the username and password if the proxy requires authentication. It can be `http://` or `https://`.
The `proxy` option can be a URL string or an object with `url` and optional `headers`. The URL can include the username and password if the proxy requires authentication. It can be `http://` or `https://`.
---
## Custom proxy headers
To send custom headers to the proxy server (useful for proxy authentication tokens, custom routing, etc.), use the object format:
```ts proxy-headers.ts icon="/icons/typescript.svg"
await fetch("https://example.com", {
proxy: {
url: "https://proxy.example.com:8080",
headers: {
"Proxy-Authorization": "Bearer my-token",
"X-Proxy-Region": "us-east-1",
},
},
});
```
The `headers` property accepts a plain object or a `Headers` instance. These headers are sent directly to the proxy server in `CONNECT` requests (for HTTPS targets) or in the proxy request (for HTTP targets).
If you provide a `Proxy-Authorization` header, it will override any credentials specified in the proxy URL.
---
## Environment variables
You can also set the `$HTTP_PROXY` or `$HTTPS_PROXY` environment variable to the proxy URL. This is useful when you want to use the same proxy for all requests.
```sh terminal icon="terminal"
HTTPS_PROXY=https://usertitle:password@proxy.example.com:8080 bun run index.ts
HTTPS_PROXY=https://username:password@proxy.example.com:8080 bun run index.ts
```

View File

@@ -6,7 +6,7 @@ mode: center
This starts an HTTP server listening on port `3000`. It demonstrates basic routing with a number of common responses and also handles POST data from standard forms or as JSON.
See [`Bun.serve`](https://bun.com/docs/api/http) for details.
See [`Bun.serve`](/runtime/http/server) for details.
```ts server.ts icon="/icons/typescript.svg"
const server = Bun.serve({

View File

@@ -6,7 +6,7 @@ mode: center
This starts an HTTP server listening on port `3000`. It responds to all requests with a `Response` with status `200` and body `"Welcome to Bun!"`.
See [`Bun.serve`](https://bun.com/docs/api/http) for details.
See [`Bun.serve`](/runtime/http/server) for details.
```ts server.ts icon="/icons/typescript.svg"
const server = Bun.serve({

View File

@@ -4,7 +4,7 @@ sidebarTitle: Stream file response
mode: center
---
This snippet reads a file from disk using [`Bun.file()`](https://bun.com/docs/api/file-io#reading-files-bun-file). This returns a `BunFile` instance, which can be passed directly into the `new Response` constructor.
This snippet reads a file from disk using [`Bun.file()`](/runtime/file-io#reading-files-bun-file). This returns a `BunFile` instance, which can be passed directly into the `new Response` constructor.
```ts server.ts icon="/icons/typescript.svg"
const path = "/path/to/file.txt";
@@ -32,7 +32,7 @@ new Response(Bun.file("./img.png")).headers.get("Content-Type");
---
Putting it all together with [`Bun.serve()`](https://bun.com/docs/api/http#bun-serve).
Putting it all together with [`Bun.serve()`](/runtime/http/server).
```ts server.ts icon="/icons/typescript.svg"
// static file server
@@ -47,4 +47,4 @@ Bun.serve({
---
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()`.

View File

@@ -4,7 +4,7 @@ sidebarTitle: Configure TLS
mode: center
---
Set the `tls` key to configure TLS. Both `key` and `cert` are required. The `key` should be the contents of your private key; `cert` should be the contents of your issued certificate. Use [`Bun.file()`](https://bun.com/docs/api/file-io#reading-files-bun-file) to read the contents.
Set the `tls` key to configure TLS. Both `key` and `cert` are required. The `key` should be the contents of your private key; `cert` should be the contents of your issued certificate. Use [`Bun.file()`](/runtime/file-io#reading-files-bun-file) to read the contents.
```ts server.ts icon="/icons/typescript.svg"
const server = Bun.serve({

View File

@@ -25,4 +25,4 @@ This will add the package to `devDependencies` in `package.json`.
---
See [Docs > Package manager](https://bun.com/docs/cli/install) for complete documentation of Bun's package manager.
See [Docs > Package manager](/pm/cli/install) for complete documentation of Bun's package manager.

View File

@@ -37,4 +37,4 @@ bun add github:colinhacks/zod
---
See [Docs > Package manager](https://bun.com/docs/cli/install) for complete documentation of Bun's package manager.
See [Docs > Package manager](/pm/cli/install) for complete documentation of Bun's package manager.

View File

@@ -24,4 +24,4 @@ This will add the package to `optionalDependencies` in `package.json`.
---
See [Docs > Package manager](https://bun.com/docs/cli/install) for complete documentation of Bun's package manager.
See [Docs > Package manager](/pm/cli/install) for complete documentation of Bun's package manager.

View File

@@ -17,7 +17,7 @@ This will add the package to `peerDependencies` in `package.json`.
```json package.json icon="file-json"
{
"peerDependencies": {
"@types/bun": "^1.3.2" // [!code ++]
"@types/bun": "^1.3.3" // [!code ++]
}
}
```
@@ -26,14 +26,14 @@ This will add the package to `peerDependencies` in `package.json`.
Running `bun install` will install peer dependencies by default, unless marked optional in `peerDependenciesMeta`.
{/* prettier-ignore */}
```json package.json icon="file-json"
{
"peerDependencies": {
"@types/bun": "^1.3.2"
"@types/bun": "^1.3.3"
},
"peerDependenciesMeta": {
"@types/bun": {
// [!code ++]
"@types/bun": { // [!code ++]
"optional": true // [!code ++]
} // [!code ++]
}
@@ -42,4 +42,4 @@ Running `bun install` will install peer dependencies by default, unless marked o
---
See [Docs > Package manager](https://bun.com/docs/cli/install) for complete documentation of Bun's package manager.
See [Docs > Package manager](/pm/cli/install) for complete documentation of Bun's package manager.

View File

@@ -32,4 +32,4 @@ import { z } from "zod";
---
See [Docs > Package manager](https://bun.com/docs/cli/install) for complete documentation of Bun's package manager.
See [Docs > Package manager](/pm/cli/install) for complete documentation of Bun's package manager.

View File

@@ -41,4 +41,4 @@ bun add zod@next
---
See [Docs > Package manager](https://bun.com/docs/cli/install) for complete documentation of Bun's package manager.
See [Docs > Package manager](/pm/cli/install) for complete documentation of Bun's package manager.

View File

@@ -31,9 +31,9 @@ password = "$NPM_PASSWORD"
---
Then assign your Azure Personal Access Token to the `NPM_PASSWORD` environment variable. Bun [automatically reads](https://bun.com/docs/runtime/env) `.env` files, so create a file called `.env` in your project root. There is no need to base-64 encode this token! Bun will do this for you.
Then assign your Azure Personal Access Token to the `NPM_PASSWORD` environment variable. Bun [automatically reads](/runtime/environment-variables) `.env` files, so create a file called `.env` in your project root. There is no need to base-64 encode this token! Bun will do this for you.
```txt .env icon="settings"
```ini .env icon="settings"
NPM_PASSWORD=<paste token here>
```
@@ -43,7 +43,7 @@ NPM_PASSWORD=<paste token here>
---
To configure Azure Artifacts without `bunfig.toml`, you can set the `NPM_CONFIG_REGISTRY` environment variable. The URL should include `:username` and `:_password` as query parameters. Replace `<USERNAME>` and `<PASSWORD>` with the apprropriate values.
To configure Azure Artifacts without `bunfig.toml`, you can set the `NPM_CONFIG_REGISTRY` environment variable. The URL should include `:username` and `:_password` as query parameters. Replace `<USERNAME>` and `<PASSWORD>` with the appropriate values.
```bash terminal icon="terminal"
NPM_CONFIG_REGISTRY=https://pkgs.dev.azure.com/my-azure-artifacts-user/_packaging/my-azure-artifacts-user/npm/registry/:username=<USERNAME>:_password=<PASSWORD>

View File

@@ -20,7 +20,7 @@ registry = "https://usertitle:password@registry.npmjs.org"
---
Your `bunfig.toml` can reference environment variables. Bun automatically loads environment variables from `.env.local`, `.env.[NODE_ENV]`, and `.env`. See [Docs > Environment variables](https://bun.com/docs/runtime/env) for more information.
Your `bunfig.toml` can reference environment variables. Bun automatically loads environment variables from `.env.local`, `.env.[NODE_ENV]`, and `.env`. See [Docs > Environment variables](/runtime/environment-variables) for more information.
```toml bunfig.toml icon="settings"
[install]
@@ -29,4 +29,4 @@ registry = { url = "https://registry.npmjs.org", token = "$npm_token" }
---
See [Docs > Package manager](https://bun.com/docs/cli/install) for complete documentation of Bun's package manager.
See [Docs > Package manager](/pm/cli/install) for complete documentation of Bun's package manager.

View File

@@ -99,7 +99,7 @@ bun update
bun update @types/bun --latest
# Update a dependency to a specific version
bun update @types/bun@1.3.2
bun update @types/bun@1.3.3
# Update all dependencies to the latest versions
bun update --latest

View File

@@ -6,7 +6,8 @@ mode: center
<Note>
Bun v1.1.39 introduced `bun.lock`, a JSONC formatted lockfile. `bun.lock` is human-readable and git-diffable without
configuration, at no cost to performance. [**Learn more.**](https://bun.com/docs/install/lockfile#text-based-lockfile)
configuration, at no cost to performance. In 1.2.0+ it is the default format used for new projects. [**Learn
more.**](/pm/lockfile#text-based-lockfile)
</Note>
---

View File

@@ -22,4 +22,4 @@ z.string();
---
See [Docs > Package manager](https://bun.com/docs/cli/install) for complete documentation of Bun's package manager.
See [Docs > Package manager](/pm/cli/install) for complete documentation of Bun's package manager.

View File

@@ -4,7 +4,7 @@ sidebarTitle: Configure a scoped registry
mode: center
---
Private registries can be configured using either [`.npmrc`](https://bun.com/docs/install/npmrc) or [`bunfig.toml`](https://bun.com/docs/runtime/bunfig#install-registry). While both are supported, we recommend using **bunfig.toml** for enhanced flexibility and Bun-specific options.
Private registries can be configured using either [`.npmrc`](/pm/npmrc) or [`bunfig.toml`](/runtime/bunfig#install-registry). While both are supported, we recommend using **bunfig.toml** for enhanced flexibility and Bun-specific options.
To configure a registry for a particular npm scope:
@@ -28,7 +28,7 @@ To configure a registry for a particular npm scope:
---
Your `bunfig.toml` can reference environment variables. Bun automatically loads environment variables from `.env.local`, `.env.[NODE_ENV]`, and `.env`. See [Docs > Environment variables](https://bun.com/docs/runtime/env) for more information.
Your `bunfig.toml` can reference environment variables. Bun automatically loads environment variables from `.env.local`, `.env.[NODE_ENV]`, and `.env`. See [Docs > Environment variables](/runtime/environment-variables) for more information.
```toml bunfig.toml icon="settings"
[install.scopes]
@@ -37,4 +37,4 @@ Your `bunfig.toml` can reference environment variables. Bun automatically loads
---
See [Docs > Package manager](https://bun.com/docs/cli/install) for complete documentation of Bun's package manager.
See [Docs > Package manager](/pm/cli/install) for complete documentation of Bun's package manager.

View File

@@ -8,7 +8,9 @@ Unlike other npm clients, Bun does not execute arbitrary lifecycle scripts for i
<Note>
Bun includes a default allowlist of popular packages containing `postinstall` scripts that are known to be safe. You
can see this list [here](https://github.com/oven-sh/bun/blob/main/src/install/default-trusted-dependencies.txt).
can see this list [here](https://github.com/oven-sh/bun/blob/main/src/install/default-trusted-dependencies.txt). This
default list only applies to packages installed from npm. For packages from other sources (such as `file:`, `link:`,
`git:`, or `github:` dependencies), you must explicitly add them to `trustedDependencies`.
</Note>
---
@@ -47,4 +49,4 @@ bun install
---
See [Docs > Package manager > Trusted dependencies](https://bun.com/docs/install/lifecycle) for complete documentation of trusted dependencies.
See [Docs > Package manager > Trusted dependencies](/pm/lifecycle) for complete documentation of trusted dependencies.

View File

@@ -67,4 +67,4 @@ bun add zod
---
See [Docs > Package manager](https://bun.com/docs/cli/install) for complete documentation of Bun's package manager.
See [Docs > Package manager](/pm/cli/install) for complete documentation of Bun's package manager.

View File

@@ -6,12 +6,13 @@ mode: center
<Note>
Bun v1.1.39 introduced `bun.lock`, a JSONC formatted lockfile. `bun.lock` is human-readable and git-diffable without
configuration, at no cost to performance. [**Learn more.**](https://bun.com/docs/install/lockfile#text-based-lockfile)
configuration, at no cost to performance. In 1.2.0+ it is the default format used for new projects. [**Learn
more.**](/pm/lockfile#text-based-lockfile)
</Note>
---
Use the `--yarn` flag to generate a Yarn-compatible `yarn.lock` file (in addition to `bun.lock`).
Use the `--yarn` flag to generate a Yarn-compatible `yarn.lock` file (in addition to `bun.lock{b}`).
```sh terminal icon="terminal"
bun install --yarn
@@ -47,4 +48,4 @@ abab@^2.0.6:
---
See [Docs > Package manager](https://bun.com/docs/cli/install) for complete documentation of Bun's package manager.
See [Docs > Package manager](/pm/cli/install) for complete documentation of Bun's package manager.

View File

@@ -15,4 +15,4 @@ process.on("SIGINT", () => {
---
See [Docs > API > Utils](https://bun.com/docs/api/utils) for more useful utilities.
See [Docs > API > Utils](/runtime/utils) for more useful utilities.

Some files were not shown because too many files have changed in this diff Show More