You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
73d6fb Refactor telemetry channel initialization by removing unnecessary options in common-preset.ts
6ebe66 Merge branch 'next' into norbert/share-channel-events
50a69c Enhance telemetry functionality by adding share-related events and updating ESLint rules. Introduce new events for sharing story links, isolating modes, and popover openings. Update telemetry channel to handle these events and create corresponding tests for payload generation.
73d6fb Refactor telemetry channel initialization by removing unnecessary options in common-preset.ts
6ebe66 Merge branch 'next' into norbert/share-channel-events
50a69c Enhance telemetry functionality by adding share-related events and updating ESLint rules. Introduce new events for sharing story links, isolating modes, and popover openings. Update telemetry channel to handle these events and create corresponding tests for payload generation.
73d6fb Refactor telemetry channel initialization by removing unnecessary options in common-preset.ts
6ebe66 Merge branch 'next' into norbert/share-channel-events
50a69c Enhance telemetry functionality by adding share-related events and updating ESLint rules. Introduce new events for sharing story links, isolating modes, and popover openings. Update telemetry channel to handle these events and create corresponding tests for payload generation.
73d6fb Refactor telemetry channel initialization by removing unnecessary options in common-preset.ts
6ebe66 Merge branch 'next' into norbert/share-channel-events
50a69c Enhance telemetry functionality by adding share-related events and updating ESLint rules. Introduce new events for sharing story links, isolating modes, and popover openings. Update telemetry channel to handle these events and create corresponding tests for payload generation.
73d6fb Refactor telemetry channel initialization by removing unnecessary options in common-preset.ts
6ebe66 Merge branch 'next' into norbert/share-channel-events
50a69c Enhance telemetry functionality by adding share-related events and updating ESLint rules. Introduce new events for sharing story links, isolating modes, and popover openings. Update telemetry channel to handle these events and create corresponding tests for payload generation.
73d6fb Refactor telemetry channel initialization by removing unnecessary options in common-preset.ts
6ebe66 Merge branch 'next' into norbert/share-channel-events
50a69c Enhance telemetry functionality by adding share-related events and updating ESLint rules. Introduce new events for sharing story links, isolating modes, and popover openings. Update telemetry channel to handle these events and create corresponding tests for payload generation.
0f43ea perf(structuredClone): add fast path for root-level dense arrays (#26814)
Summary
Add a fast path for structuredClone and postMessage when the root
value is a dense array of primitives or strings. This bypasses the full CloneSerializer/CloneDeserializer machinery by keeping data in
native C++ structures instead of serializing to a byte stream.
Important: This optimization only applies when the root value passed
to structuredClone() / postMessage() is an array. Nested arrays
within objects still go through the normal serialization path.
Implementation
Three tiers of array fast paths, checked in order:
Tier
Indexing Type
Strategy
Applies When
Tier 1
ArrayWithInt32
memcpy butterfly data
Dense int32
array, no holes, no named properties
Tier 2
ArrayWithDouble
memcpy butterfly data
Dense
double array, no holes, no named properties
Tier 3
ArrayWithContiguous
Copy elements into
FixedVector<variant<JSValue, String>>
Dense array of
primitives/strings, no holes, no named properties
All tiers fall through to the normal serialization path when:
The array has holes that must forward to the prototype
The array has named properties (e.g., arr.foo = "bar") — checked via structure->maxOffset() != invalidOffset
Elements contain non-primitive, non-string values (objects, arrays,
etc.)
The context requires wire-format serialization (storage, cross-process
transfer)
Deserialization
Tier 1/2: Allocate a new Butterfly via vm.auxiliarySpace(), memcpy data back, create array with JSArray::createWithButterfly().
Falls back to normal deserialization if isHavingABadTime (forced
ArrayStorage mode).
Tier 3: Pre-convert elements to JSValue (including jsString()
allocation), then use JSArray::tryCreateUninitializedRestricted() + initializeIndex().
Benchmarks
Apple M4 Max, comparing system Bun 1.3.8 vs this branch (release build):
Benchmark
Before
After
Speedup
structuredClone([10 numbers])
308.71 ns
40.38 ns
7.6x
structuredClone([100 numbers])
1.62 µs
86.87 ns
18.7x
structuredClone([1000 numbers])
13.79 µs
544.56 ns
25.3x
structuredClone([10 strings])
642.38 ns
307.38 ns
2.1x
structuredClone([100 strings])
5.67 µs
2.57 µs
2.2x
structuredClone([10 mixed])
446.32 ns
198.35 ns
2.3x
structuredClone(nested array)
1.84 µs
1.79 µs
1.0x (not
eligible)
structuredClone({a: 123})
95.98 ns
100.07 ns
1.0x (no
regression)
Int32 arrays see the largest gains (up to 25x) since they use a direct memcpy of butterfly memory. String/mixed arrays see ~2x improvement.
No performance regression on non-eligible inputs.
Bug Fix
Also fixes a correctness bug where arrays with named properties (e.g., arr.foo = "bar") would lose those properties when going through the
array fast path. Added a structure->maxOffset() != invalidOffset guard
to fall back to normal serialization for such arrays.
Fixed a minor double-counting issue in computeMemoryCost where JSValue elements in SimpleArray were counted both by byteSize()
and individually.
Test Plan
38 tests in test/js/web/structured-clone-fastpath.test.ts covering:
Prototype modification (custom prototype, indexed prototype properties
with holes)
Array subclass identity loss (per spec)
undefined-only and null-only arrays
Multiple independent clones from the same source
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
088989 Revert "feat(bundler): add configurable CJS→ESM unwrapping via unwrapCJSToESM"
This reverts commit e3c25260ed9916849f87cc1bc50633f9df0ee928.
e3c252 feat(bundler): add configurable CJS→ESM unwrapping via unwrapCJSToESM
Add minify.unwrapCJSToESM JS API option and --unwrap-cjs-to-esm CLI
flag to force CJS-to-ESM conversion for specific packages, eliminating
the __commonJS wrapper. Supports wildcard patterns (e.g. "@​scope/*").
User entries extend the default React family list.
Also removes the react/react-dom version check that gated conversion,
and fixes packageName() to handle scoped packages (@​scope/pkg).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1bded8 types: Enable --splitting with compile (#26796)
This reverts commit c63415c9c993546f8b9b34e359bee0c1ddaadade.
What does this PR do?
How did you verify your code works?
89d2b1 fix(websocket): add missing incPendingActivityCount() in blob binaryType case (#26670)
Summary
Fix crash ("Pure virtual function called!") when WebSocket client
receives binary data with binaryType = "blob" and no event listener
attached
Add missing incPendingActivityCount() call before postTask in the
Blob case of didReceiveBinaryData
Add regression test for issue #26669
Root Cause
The Blob case in didReceiveBinaryData (WebSocket.cpp:1324-1331) was
calling decPendingActivityCount() inside the postTask callback
without a matching incPendingActivityCount() beforehand. This bug was
introduced in #21471 when Blob support was added.
The ArrayBuffer and NodeBuffer cases correctly call incPendingActivityCount() before postTask, but the Blob case was
missing this call.
Test plan
New regression test verifies WebSocket with binaryType = "blob"
doesn't crash on ping frames
bun bd test test/regression/issue/26669.test.ts passes
0ad562 fix(http2) Fix SSLWrapper and allow injecting connections in Http2SecureServer (#26539)
What does this PR do?
Enables the net.Server → Http2SecureServer connection upgrade pattern
used by libraries like http2-wrapper, crawlee, and custom HTTP/2 proxy
servers. This pattern works by accepting raw TCP connections on a net.Server and forwarding them to an Http2SecureServer via h2Server.emit('connection', rawSocket).
Bug fixes
SSLWrapper use-after-free (Zig)
Two use-after-free bugs in ssl_wrapper.zig are fixed:
flush() stale pointer — flush() captured the ssl pointer before calling handleTraffic(), which can trigger a close callback
that frees the SSL object via deinit. The pointer was then used after
being freed. Fix: read this.sslafterhandleTraffic() returns.
handleReading() null dereference — handleReading() called triggerCloseCallback() after triggerDataCallback() without checking
whether the data callback had already closed the connection. This led to
a null function pointer dereference. Fix: check this.ssl == null || this.flags.closed_notified before calling the close callback.
63a323 fix(http): don't enter tunnel mode for proxy-style absolute URLs in request line (#26737)
Summary
Fixes a bug where sequential HTTP requests with proxy-style absolute
URLs (e.g. GET http://example.com/path HTTP/1.1) hang on the 2nd+
request when using keep-alive connections.
Root Cause
In packages/bun-uws/src/HttpParser.h, the parser was treating
proxy-style absolute URLs identically to CONNECT method requests —
setting isConnectRequest = true and entering tunnel mode. This flag
was never reset between requests on the same keep-alive connection, so
the 2nd+ request was swallowed as raw tunnel data instead of being
parsed as HTTP.
Fix
3-line change in HttpParser.h:569:
isConnect: Now only matches actual CONNECT method requests
(removed isHTTPorHTTPSPrefixForProxies from the condition)
isProxyStyleURL: New variable that detects http:///https://
prefixes and accepts them as valid request targets — without triggering
tunnel mode
Who was affected
Any Bun HTTP server (Bun.serve() or node:http createServer)
receiving proxy-style requests on keep-alive connections
HTTP proxy servers built with Bun could only handle one request per
connection
Bun's own HTTP client making sequential requests through an HTTP proxy
backed by a Bun server
Test
Added test/js/node/http/node-http-proxy-url.test.ts with 3 test cases:
Sequential GET requests with absolute URL paths
Sequential POST requests with absolute URL paths
Mixed normal and proxy-style URLs
Tests run under both Node.js and Bun for compatibility verification.
❌ Fails with system bun (2/3 tests timeout on 2nd request)
315e82 fix(bindgen): prevent use-after-free for optional string arguments (#26717)
Summary
Fix a use-after-free bug in the bindgen code generator where string
arguments with default values would have their underlying WTF::String
destroyed before the BunString was used
The issue occurred because for optional string parameters with
defaults, a WTF::String was created inside an if block, converted to
BunString, then the if block closed and destroyed the WTF::String while
the BunString was still in use
This manifested as a segfault in Bun.stringWidth() and potentially
other functions using optional string arguments
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
7f498a chore: improve markdown to html perf (#26644)
What does this PR do?
I was looking at the recent
support for markdown and did
some benchmarking against bindings i
created for my lo runtime to md4c. In some cases, Bun is quite a bit
slower, so i did a bit of digging and came up with this change. It uses indexOfAny which should utilise SIMD where it's available to scan
ahead in the payload for characters that need escaping.
In benchmarks
I have done this results in anywhere from 3% to ~15% improvement in
throughput. The bigger the payload and the more space between entities
the bigger the gain afaict, which would make sense.
How did you verify your code works?
It passes test/js/bun/md/*.test.ts running locally. Only tested on
macos. Can test on linux but I assume that will happen in CI anyway?
main
patched
5d4b18 [publish images] test windows aarch64 CI (#26701)
What does this PR do?
How did you verify your code works?
41de7a [publish images] Upgrade LLVM toolchain from 19.1.7 to 21.1.8 (#26667)
Summary
Update LLVM version references across build scripts, Dockerfiles, CI,
Nix configs, and documentation
Fix LLVM 21 -Wcharacter-conversion errors in WebKit bindings:
EncodingTables.h: pragma for intentional char32_t/char16_t
comparisons
TextCodecCJK.cpp: widen gb18030AsymmetricEncode param to char32_t
URLPatternParser: widen isValidNameCodepoint param to char32_t,
cast for startsWith
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
d23312 feat(test): add Symbol.dispose support to mock/spyOn (#26692)
Summary
Add [Symbol.dispose] to mock function prototype, aliased to mockRestore
Enables using spy = spyOn(obj, "method") to auto-restore when
leaving scope
Works for both spyOn() and mock()
Addresses #6040 — gives users a clean way to scope spy lifetimes instead
of manually calling mockRestore() or relying on afterEach.
Example
import{spyOn,expect,test}from"bun:test";test("auto-restores spy",()=>{constobj={method: ()=>"original"};{
using spy=spyOn(obj,"method").mockReturnValue("mocked");expect(obj.method()).toBe("mocked");}// automatically restoredexpect(obj.method()).toBe("original");});
Test plan
bun bd test test/js/bun/test/mock-disposable.test.ts — 3 tests pass
Verified tests fail with USE_SYSTEM_BUN=1
de8c75 perf(markdown): cache tag strings in React renderer (#26668)
Summary
Cache frequently-used HTML tag strings (div, p, h1-h6, etc.) in GlobalObject using LazyProperty<JSGlobalObject, JSString> instead of
creating new JSStrings on every React element creation in Bun.markdown.react().
Changes
Added BunMarkdownTagStrings.h/.cpp with 30 cached tag strings
Modified MarkdownObject.zig to use cached strings via C API
Integrated with ZigGlobalObject for proper GC visiting
Benchmark Results
All benchmarks performed on Apple M4 Max with release builds.
mitata Benchmark (Bun.markdown.react)
Size
Main
Feature
Improvement
small (121 chars)
3.20 µs
2.30 µs
28% faster
medium (1039 chars)
15.09 µs
14.02 µs
7% faster
large (20780 chars)
288.48 µs
267.14 µs
7.4% faster
Heap Profile
Metric
Main
Feature
Improvement
Heap size
500.7 KB
469.7 KB
6% reduction
Object count
12,000
10,315
14% reduction
String count
4,248
2,563
40% reduction
String size
97.1 KB
65.8 KB
32% reduction
HTTP Request Benchmark (ab -n 10000 -c 20)
Metric
Main
Feature
Improvement
Requests/sec
7,710
8,174
6% faster
Time/request
2.59 ms
2.45 ms
5% faster
p99 latency
6 ms
3 ms
50% improvement
Technical Details
The optimization uses JSC's LazyProperty pattern (similar to BunCommonStrings and BunHttp2CommonStrings) to lazily initialize and
cache tag strings on first use. This avoids repeated bun.String.createUTF8ForJS calls which allocate new JSStrings for the
same tag names on every markdown element.
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
27e136 Make GC release access skip interval configurable (#26699)
Summary
Make defaultRemainingRunsUntilSkipReleaseAccess configurable at
runtime instead of a compile-time constant
Add BUN_GC_RUNS_UNTIL_SKIP_RELEASE_ACCESS environment variable to
control how many idle event loop iterations pass before skipping JSC
heap releaseAccess calls in onBeforeWait
Default remains 10, matching the previous hardcoded value
Test plan
Verify default behavior is unchanged (no env var set, value is 10)
Verify BUN_GC_RUNS_UNTIL_SKIP_RELEASE_ACCESS=0 causes release
access to be skipped every iteration
Verify BUN_GC_RUNS_UNTIL_SKIP_RELEASE_ACCESS=100 delays skipping
for 100 idle iterations
Verify negative values are ignored (default is preserved)
Verify non-numeric values are ignored (default is preserved)
Changelog
🤖 Generated with Claude Code (0%
3-shotted by claude)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
eba4da perf: skip Event creation in AbortSignal.abort() when no listeners (#26686)
Summary
This is a tiny optimization that skips creating and dispatching an Event
object when AbortSignal.abort() is called with no registered
listeners.
Changes
When there are no listeners (no addEventListener or onabort), we now
check hasEventListeners() before creating the Event, avoiding:
9d68ec require --compile for ESM bytecode (#26624)
Summary
Add validation to require --compile when using ESM bytecode
Update documentation to clarify ESM bytecode requirements
Why
ESM module resolution is two-phase: (1) analyze imports/exports, (2)
evaluate. Without --compile, there's no module_info embedded, so JSC
must still parse the file for module analysis even with bytecode -
causing a double-parse deopt.
Changes
CLI: Error when --bytecode --format=esm is used without --compile
JS API: Error when bytecode: true, format: 'esm' is used without compile: true
Docs: Update bytecode.mdx, executables.mdx, index.mdx to clarify
requirements
Types: Update JSDoc for bytecode option in bun.d.ts
Test plan
# Should error
bun build ./test.js --bytecode --format=esm --outdir=./out
# error: ESM bytecode requires --compile. Use --format=cjs for bytecode without --compile.# Should work
bun build ./test.js --bytecode --format=esm --compile --outfile=./mytest
bun build ./test.js --bytecode --format=cjs --outdir=./out
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Adds --cpu-prof-interval to configure the CPU profiler sampling
interval in microseconds (default: 1000), matching Node.js's --cpu-prof-interval flag.
bun --cpu-prof --cpu-prof-interval 500 index.js
Parsed as u32, truncated to c_int when passed to JSC's SamplingProfiler::setTimingInterval
Invalid values silently fall back to the default (1000μs)
Warns if used without --cpu-prof or --cpu-prof-md
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
56b5be fix(shell): prevent double-free during GC finalization (#26626)
Summary
Fixes #26625
This fixes a segmentation fault that occurred on Windows x64 when the GC
finalizer tried to free shell interpreter resources that were already
partially freed during normal shell completion.
Added explicit cleanup_state enum to track resource ownership state
needs_full_cleanup: Nothing cleaned up yet, finalizer must clean
everything
runtime_cleaned: finish() already cleaned IO/shell, finalizer
skips those
Early return in #derefRootShellAndIOIfNeeded() when already cleaned
Explicit state-based cleanup in deinitFromFinalizer()
The vulnerability existed on all platforms but was most reliably
triggered on Windows with high GC pressure (many concurrent shell
commands).
Test plan
Build passes (bun bd)
New regression test added (test/regression/issue/26625.test.ts)
Existing shell tests pass (same 4 pre-existing failures, no new
failures)
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Updated Packages