bun
Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one
by oven-shRust
Commit activity
Last 12 weeks · 1206 commits
Community health
5 of 6 standards met
Recent PRs & issues
What does this PR do? Adds WebGPU ( and the classes) for compute shaders and rendering to textures. There is no canvas and no option that turns it off. Dawn is built from source: Direct3D 12 on Windows, Metal on macOS, Vulkan elsewhere. The first loads the system libraries. is the IDL as a bindgen schema, and bindgen gains the WebIDL features that takes. Dawn frees memory only after the next submit, so an empty one is made when the queue runs dry. The binary grows by 3.6 to 4.4 MB, which removes. The bound on an untrimmed executable in goes up with it. Building Bun now needs Python. Left out: , , , , and DXC, so Windows has no or . Known limits: executables deny themselves executable memory on Linux 6.7+. CPU drivers need it, so skips them there. Proprietary GPU drivers are untested. copies a mapped range where the spec throws. A shader with a call chain thousands deep overflows the stack in the shader compiler. The collector waits for the GPU when it destroys a busy device. A result can continue the program while a macro waits, as timers and sockets do. Dawn keeps the blocks of resources below 4 MB until the device is destroyed. Outside WebGPU: The event loop gains , which it asks before and after each poll. Results arrive through it, whether the regular loop or that of a macro runs. The trim tool reads Mach-O objects compiled from Objective-C. The table of built-ins is more exact about and , which kept WebGPU in most trimmed programs. no longer has unwritten slots in its frame. Why runGC changed printed in 51 of 60 runs of a release build with ASAN, and in 0 of 60 after the change. Other inlining in the Rust thunk above had moved its frame onto two words that an allocation slow path left behind: a red zone, and the of the branch not taken. Stopped in before , with a built from there: With those two words zeroed, the snapshot has 2699 nodes and lacks the cell, and the program prints in 8 of 8 runs. How did you verify your code works? and fail on the released Bun. In CI they run on a device on Linux x64 (SwiftShader, also with ASAN), macOS x64 and arm64 (Metal) and Windows x64 and arm64 (Direct3D 12). The CI images of Linux arm64 and Alpine have no Vulkan driver, so what needs a device is skipped there. Android and FreeBSD are only built. Device loss, failing waits and delays of the waiting thread were injected by hand with a Vulkan layer. No test in CI covers them. The CTS was run by hand on Linux x64 with two CPU drivers, lavapipe and SwiftShader. API tests: 48,018 pass on at least one driver, 86 fail on both, 235 fail on the only driver that runs them. These trace to known Dawn failures (31), driver behavior (287), the omitted API (2) and test order (1). Shader validation: 47,427 pass, 2 fail on unshipped features. A sample of shader execution: 8,025 pass, 48 fail. _Generated by Claude Code_
Summary Fixes issue #19953. console.assert(false, 'message') was printing only message instead of the expected Assertion failed: message. Root cause In src/jsc/ConsoleObject.rs, the Rust-side message_with_type_and_level_ function handled MessageType::Assert only when the argument list was empty (the bare console.assert(false) case). When the caller provided additional message values, execution fell through to the generic ormat2 path without prepending the required Assertion failed: prefix. Additionally, the stderr writer and stderr ANSI color settings were selected solely based on MessageLevel, not on MessageType::Assert, so assert messages could go to stdout with the wrong colors. Changes 1. When message_type == MessageType::Assert and the value list is non-empty, write the leading indent, then the red-colored (when enabled) Assertion failed: prefix before letting ormat2 format the remaining values. default_indent is reset to 0 so ormat2 does not duplicate the indent. 2. Route MessageType::Assert through the stderr writer and stderr ANSI color settings, matching Node.js behavior. Test plan \un -e 'console.assert(false)'\ → prints \Assertion failed\ (unchanged) \un -e 'console.assert(false, "msg")'\ → prints \Assertion failed: msg\ (was \msg\) \un -e 'console.assert(false, "a", "b")'\ → prints \Assertion failed: a b\ \un -e 'console.assert(true, "msg")'\ → produces no output (unchanged) 🤖🤖🤖
Problem A VS Code breakpoint on a method after another method shows on an earlier line and never pauses: JSC binds it to the before it. () searches the whole file. An indented line has no mapping at column 0, so an earlier token answers. Fix A breakpoint goes to the generated line of the first tokens of its line. A place before the first token of a generated line ( since #45677, a ) is reported on that token's line. answers with a message when JSC gives no location. main answers . Verified: (53 of 123 tests fail with main's package). It replaces the package test , which fails on main: , expected 4. Self-reviewed: 26 concerns raised, 24 addressed. Not done: 1-based async stack frame lines (a separate defect), and placing a from (the printer can map it). Background A token is one segment of . Bun's printer gives none to or a function's , and copies the previous segment to column 0 of each line without one. decodes without . Filling the table from costs 80.5 M instructions per first lookup (main 32.6 M, here 27.0 M). Downsides 10,189 of 1,051,199 line breakpoints in repo files bind to other code (Bun 1.4.4). None leaves its own code. 86,466 lines (8.2%) still bind to an indented and never pause (main: 94,635). Notes History. #4186 added the package test while returned a 1-based line without conversion, so two errors of one line cancelled. #4380 fixed the conversion, and the test has failed since. Nothing under imported the package, so CI never ran it. The rule, original to generated. A request at or after a token of its line: the first place where the printer printed that token. A line without tokens (blank, a comment, a lone ): the answer of main. It is the first mapping of the token before the line, which is its copy at the start of the next generated line when there is one. A request before the first token of its line: the code of the line starts at the first of its tokens that the printer printed after that mapping. When that place is in the generated line of the mapping, the mapping answers, as on main. Otherwise column 0 of the generated line of that place answers, so that JSC does not stop at a on the way. Two cases change "the first of its tokens". A token that the printer prints again in the same run of the line is a declaration (a parameter property is a class field first): then the first token of the line answers. When the printer moved the whole line before the code before it, the first run of the line answers. The rule, generated to original. The last token of the generated line at or before the place answers. Before the first token of the line, that token answers, unless the printer printed it again and it maps back: after an enum maps to the first line of the enum. How it was measured. Real JSC. For every original line, the lookup of main and the lookup of this branch each give a place, and says where that place binds. "Own code" is a generated line that holds a token of the requested line. The runtime parsed each file under the inspector without running it. Corpus: 2,743 ES modules of this repo (TypeScript, 3 of them TSX), 92% of their lines under . More runs of the same walk, lines that leave their own code: 0 on Bun 1.4.2, 1.3.14 (1,042,107 lines), 1.2.23 (446,930 lines) and 1.1.45 (446,753 lines), and 0 of 282,845 lines in 4,069 files of (3,814 of them CommonJS, Bun 1.4.4, 7,152 lines bind to other code). JSC lists the of a function as a pause position and reports the frame one column after it. The first rows are at the listed column, where a breakpoint resolves. Bun 1.4.4, both lookups and JSC together: of 740,052 lines with code, a breakpoint is reported on its own line for 348,631 on main and 387,818 here. 46,181 lines gain this. 7,007 lose it, with the same binding: for 6,526 the reported line is now the line of the code that JSC bound, and 481 are a before a token of a later line. Cost. is not installed here. Instructions are user-mode counts from (), main against this branch, five interleaved runs each, under node v26.3.0. The map is the one that the runtime makes for (8,558 segments). The bun binary does not change. The decoder. The fix needs the segments in generated order and in original order. gives them through , one object and one computed source name per segment: the first lookup of a map then costs 80.5 M instructions. So decodes itself (110 lines), and the second commit removes the dependency from the package, from and from the root , which had it for this package only. Compared with source-map-js 1.2.1 on 2,512 maps: 4,386,875 segments, 0 differences in the segments and in their order by original position. The names of the sources are those that source-map-js 1.2.1 makes for 1,442 of 1,444 pairs of a and a source. In the other 2 pairs the source is . An index map () is no longer read: read it on main, did not. What stays wrong. Both lookups work around two mappings that the printer does not write: the that ends a function, and . With those two mappings the lookups need no rule for them. The open #40834 adds closing-brace mappings. That is not in this change, which also has to serve released runtimes. JSC never pauses at a that ends a function and is not at column 0. A breakpoint that JSC moves there is reported as set and does nothing: 86,466 of 1,050,808 lines, 94,635 on main (Bun 1.4.4). 8,176 lines now pause, 7 no longer do. Jump to Cursor on such a line continues without a stop. A before a token of a later line ( before an argument or a on the next line) is reported on the line of that token. A callback without braces ( before an argument on the next line) also is, where main reports the line of the callback. A pause at a that is alone on its generated line is still reported on the line of the code before it. #15131 stays: the adapter holds a placeholder breakpoint at the start of a file that is not loaded, and a breakpoint that resolves to the same place is rejected. This is the first statement of most files, before and after this change. The new message can then name a breakpoint that the user did not set. JSC does not enter a function that starts on a later line (). A line whose only later code is in such functions gets no breakpoint, and now gets the new message. The second and later parameter properties of a constructor still bind after the class. JSC binds a breakpoint on an line to the export statement, so it pauses once when the module runs. Async stack frames come from with 1-based numbers, and reads them as 0-based. Most of them are one line late, before and after this change. A request on a line that already has a breakpoint gets that breakpoint as its answer, whatever its column or its condition: compares the line only. This is as on main. Tests. holds what the Bun 1.4.3 and 1.4.4 release binaries report for the fixture, with the source. writes it. Five debug sessions run against the bun under test: four on the fixture, and one that sets a breakpoint on every line with a call in the programs of (LF and CRLF). In that one, 97 of 105 lines are reported on their line. The other 8 continue a statement, or share their place to pause with the line before. Each clause has a row that fails without it: 84 single changes to and each fail at least one test. The package test file and its fixture are deleted. Its three other tests (the event allowlist, , the loopback bind of ) move to the new file, so CI runs them for the first time. The debug build of main does not compile here (, ). The tests ran with a debug build that has the missing include. The change is TypeScript only.
Repository: oven-sh/bun. Description: Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one Stars: 96690, Forks: 5282. Primary language: Rust. Languages: Rust (76.9%), C++ (11.8%), TypeScript (9.1%), C (1.2%), JavaScript (0.6%). Homepage: https://bun.com Topics: bun, bundler, javascript, javascriptcore, jsx, nodejs, npm, react, rust, rust-lang, transpiler, typescript. Latest release: bun-v1.4.4 (3w ago). Open PRs: 100, open issues: 9742. Last activity: just now. Community health: 100%. Top contributors: Jarred-Sumner, robobun, dylan-conway, nektro, cirospaciari, small-angel, Electroid, alii, colinhacks, pfgithub and others.