Skip to content

Tags: oven-sh/bun

Tags

bun-v1.4.3

Toggle bun-v1.4.3's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
`bun check`: a long chain of interfaces or classes no longer takes cu…

…bic time (#44895)

A long chain of interfaces or classes, each of which extends the last,
took cubic time.

```ts
interface I0 { k0: number }
interface I1 extends I0 { k1: number }
interface I2 extends I1 { k2: number }
// and 1,997 more
```

Twice the interfaces took eight times as long. This is old. Generated
typings are written like that.

CPU time of `bun check`, and of `tsc` 7.0.2:

| Each interface adds | Interfaces | main | this branch | `tsc` |
|---|---|---|---|---|
| a property | 500 | 0.26 s | 0.04 s | 0.09 s |
| a property | 1,000 | 2.00 s | 0.10 s | 0.19 s |
| a property | 2,000 | 15.28 s | 0.56 s | 0.68 s |
| a method | 500 | 0.28 s | 0.05 s | 0.08 s |
| a method | 1,000 | 1.86 s | 0.10 s | 0.18 s |
| a method | 2,000 | 15.56 s | 0.53 s | 0.68 s |

## Members that mention `this` or a type parameter

The same for a chain with any other kind of member, in classes too.
`tsc` is cubic there as well, so it is measured with 500 only.

CPU time of the check on one thread, and of `tsc` with
`--singleThreaded`:

| Each one adds | main, 1,000 | this branch, 1,000 | this branch, 2,000
| `tsc`, 500 |
|---|---|---|---|---|
| interface, `k: this` | 4.04 s | 0.55 s | 2.18 s | 8.70 s |
| interface, a method that returns `this` | 4.03 s | 0.68 s | 3.34 s |
8.75 s |
| generic interface, `k: T` | over 25 s | 0.45 s | 2.02 s | 10.04 s |
| class, a method without a return type | 4.37 s | 0.63 s | 3.02 s |
8.95 s |
| class, a field with an initializer | 3.59 s | 0.31 s | 1.81 s | 9.83 s
|
| class, a parameter property | 4.02 s | 0.41 s | 1.63 s | 8.92 s |
| class, a pair of accessors | 3.66 s | 0.34 s | 1.85 s | 8.26 s |

On main each of them takes over 25 s with 2,000.

The errors and the types are the same as before.

## How it was found

The arrays of #44890 were one shape of generated code that `bun check`
was slow on and `tsc` was not. So I ran 61 such shapes at 500, 1,000 and
2,000 lines, both tools on one thread, and compared the time and the
number of errors. Seed data, fixtures, tables, long unions with a
`switch`, chains of `else if`, spreads, builders, overloads, enums,
JavaScript that assigns to `exports`, `this` and prototypes, API
clients, mapped and conditional types, tuples, `satisfies`, merged
declarations, callbacks with contextual types.

This chain was the only one where `bun check` took more than twice as
long as `tsc` and more than half a second. In most of the others it
takes about half the time of `tsc`.

## How it was verified

What changes is when an inherited member counts as the same member. So:
5 kinds of owner, 12 kinds of member with and without `this`, plain,
generic, inside a generic function and merged, each in the 12 situations
where that decides something. Two interfaces with a common base that are
extended together, overriding a member with the same and with another
type, assigning both ways, unions and intersections of two heirs,
`keyof`, indexed access, spread, a chain of six. 192 programs, 2,527
errors, with the type of the member probed in each. The output is that
of `tsc`, before and after, on all threads and on one.

132 more programs try to make the base type of an heir matter to a
member from further up. Heirs that rename and wrap their type parameters
over four levels, with 10 kinds of member, outer type parameters,
mixins, classes inside generic classes and functions, bases that are
mapped types, intersections, arrays and tuples, defaults, statics,
overriding half way, a common base. Every inherited member is probed
through the last heir. 891 errors, the output of `tsc` before and after,
on all threads and on one.

`check.test.ts` has two tests, one with 2,000 interfaces and one with
1,000 of three of the other kinds. Both run into their timeout on main.

| Everything else | Result |
|---|---|
| TypeScript's own suite, 5 kinds of baseline | 100% of each, as before
|
| 2,512 small programs that once differed, against `tsc`, on all threads
and on one | no change |
| 47 real projects, on all threads and on one | the same output as main
|
| 317 builds with project references | the same output as main |
| Instructions for 9 configs, among them vscode, next.js and storybook |
+0.2% against main, and main against itself gives +0.5% |

bun-v1.4.2

Toggle bun-v1.4.2's commit message
Bump to 1.4.2

bun-v1.4.1

Toggle bun-v1.4.1's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
lexer: only treat __PURE__ as an annotation when it starts a // comme…

…nt (#41284)

### Problem
- A `//` comment that mentions `/*#__PURE__*/` as text marks the next
call as pure. Bun removes an unused pure call at runtime and in `bun
build`, without minification. So `` // `/*#__PURE__*/` `` followed by
`console.log(...)` deletes the `console.log`. In `@angular/build` this
deleted `source.appendRight(...)` and corrupted the Angular build output
(angular/angular-cli#33973).
- The cause is `scan_single_line_comment` in
`src/js_parser/lexer.rs:2087`. On any `#` or `@` in a `//` comment it
calls `scan_pragma`, which sets `has_pure_comment_before` when
`__PURE__` follows. The position in the comment does not matter.

Fixes #41275. Fixes #19355.

### Fix
- In a `//` comment, `@__PURE__` or `#__PURE__` is an annotation only
when it is the first word: only whitespace may sit between `//` and the
marker. Text after the marker is still allowed. Block comments are
unchanged.
- This deviates from esbuild, terser and rollup, which match the marker
anywhere in a comment. Those tools only act on it when minifying or tree
shaking. Bun acts on it always, so a false match deletes user code. Line
directives such as `// @ts-ignore`, `//# sourceMappingURL=` and `//
eslint-disable-next-line` use the same first-word rule. Block comments
keep the esbuild rule because a `/* */` comment cannot quote a
`/*#__PURE__*/`, and `/** @__PURE__ */` must keep working.
- Four existing tests in `test/bundler/bundler_comments.test.ts` put
text before the marker and asserted removal. They came in with the SIMD
lexer change (#19134) to exercise the scanner, and now assert that the
call is kept. `test/bundler/transpiler/transpiler.test.js:1589` was a
victim of this bug: the `@__PURE__` text in the commented-out lines
above it deleted the first `err(...)` call, which asserted a TSX-only
error for the `ts` loader. It now asserts the `ts` behavior, as in
esbuild's `ts_parser_test.go`.
- Verified: `test/bundler/bundler_comments.test.ts` (4 new cases) and
`test/cli/install/bun-run.test.ts` (1 new runtime case). Both fail on
the release binary. Also ran `test/bundler/esbuild/dce.test.ts`,
`default.test.ts`, `tsconfig.test.ts`, `bundler_minify.test.ts`,
`bundler_jsx.test.ts`, `transpiler/transpiler.test.js`,
`transpiler/react-compiler.test.ts`.

### Background
- A pure annotation (`/* @__PURE__ */ f()`) tells a bundler that the
call has no side effects. If the result is unused, the call can be
removed.
- Bun's `dead_code_elimination` parser feature is on by default, also
for `bun run`. The SExpr visitor
(`src/js_parser/visit/visit_stmt.rs:1430`) calls
`SideEffects::simplify_unused_expr` with no minify gate, and
`scan_side_effects.rs` drops a call marked `IfUnused` whose arguments
have no side effects. The docs describe pure annotation support as
"Always active".
- `has_pure_comment_before` is reset at the start of `Lexer::next()` and
read in `parse_expr_common` (`src/js_parser/parse/mod.rs:75`), which
marks the next `ECall` or `ENew` as `CanBeUnwrapped::IfUnused`.

<details><summary>Notes</summary>

Repro under bun 1.4.1:

```
$ bun -e 'function repro() {
    // `/*#__PURE__*/`
    console.log("This should not be deleted");
}
console.log(repro.toString());'
function repro() {}
```

esbuild 0.21.5 attaches the annotation to the same input but keeps the
call unless `--minify-syntax` is passed.

Alternative considered: gate the removal of a pure-marked expression
statement on `minify_syntax`, as esbuild does. That changes documented
runtime behavior and unminified `bun build` output for every correctly
annotated call, so this PR narrows what counts as an annotation instead.

A `/* see @__PURE__ for details */` block comment before a call still
marks it pure. That is the esbuild rule and is not changed here. A
quoted `/*#__PURE__*/` cannot occur inside a block comment, so the
real-world reports all come from `//` comments.

Self-reviewed: the review found the dead `transpiler.test.js` assertion
and asked for the esbuild deviation to be stated. Both are addressed
above. It also suggested gating `bun test` on `ignore_dce_annotations`.
That is a separate change and is not in this PR.

Unrelated failures seen locally with the debug build: two
`bun-build-api.test.ts` bytecode tests that time out at 5s under the
debug build.
</details>

<!-- robobun:evidence:begin -->

---

**no test proof** · iteration 5 · platform-specific test(s) that do not
run on this machine, deferring to CI, which covers all platforms:
test/cli/install/bun-run.test.ts

<!-- robobun:evidence:end -->

bun-v1.4.0

Toggle bun-v1.4.0's commit message
Fix edgecase in v8 CPU profiler

consolidation-step-7-green

Toggle consolidation-step-7-green's commit message

Verified

This commit was signed with the committer’s verified signature.
robobun robobun
step 7.sweep-wip2: snapshot before cap-raise resume

consolidation-step-5-green

Toggle consolidation-step-5-green's commit message

Verified

This commit was signed with the committer’s verified signature.
robobun robobun
step 5.fix0: route bun_s3_signing::error/Error via s3_signing mount path

consolidation-step-4-green

Toggle consolidation-step-4-green's commit message

Verified

This commit was signed with the committer’s verified signature.
robobun robobun
step 4.fix0: drop package-rename deps; apply 4.2/4.4/4.5/4.6 seds

consolidation-step-3-green

Toggle consolidation-step-3-green's commit message

Verified

This commit was signed with the committer’s verified signature.
robobun robobun
step 3.fix0: drop package-rename deps; apply 2.4/2.5/3.6 seds

consolidation-step-1-green

Toggle consolidation-step-1-green's commit message

Verified

This commit was signed with the committer’s verified signature.
robobun robobun
step 1.fix0: regenerate stale build/debug/codegen rust outputs

bun-v1.3.14

Toggle bun-v1.3.14's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Bun.serve: rename `h3`/`h1` options to `http3`/`http1` (#30583)

## What

Renames the `Bun.serve()` `ServerConfig` HTTP/3 options from the
abbreviated `h3` / `h1` to the spelled-out `http3` / `http1`.

```ts
// before
Bun.serve({ tls, h3: true, h1: false, fetch })

// after
Bun.serve({ tls, http3: true, http1: false, fetch })
```

These options have not shipped in a release yet, so this is a clean
rename with no backwards-compat aliases.

## Changes

- **`src/runtime/server/ServerConfig.zig` / `server.zig`**: rename the
`ServerConfig` struct fields and the JS option lookups (`arg.get(global,
"http3")`, etc.); update the validation error messages and the
unix-socket warning.
- **`packages/bun-types/serve.d.ts`**: rename the type declarations,
drop the incorrect "(and HTTP/2)" from the `http1` JSDoc (Bun.serve does
not support HTTP/2), and mark both options `@experimental`.
- **`docs/runtime/http/server.mdx`**: add an "HTTP/3 (QUIC)" section
documenting `http3` / `http1`, Alt-Svc, the unix-socket limitation, and
the experimental status.
- **Tests**: update `Bun.serve({ http3, http1 })` call sites, test
names, and the validation error-message assertion across the HTTP/3
suites (`serve-http3.test.ts`, `serve-protocols.test.ts`,
`body-stream.test.ts`, `fetch-http3-client.test.ts`,
`fetch-http3-adversarial.test.ts`, `direct-readable-stream.test.tsx`,
`fetch-h3.ts`, `packages/h3blast/`).

## Notes

- The internal `uws.AnyRequest` union variants (`.h1`/`.h3`) are left
as-is — those tag a transport, not a config option.
- The `fetch()` `protocol` option (`"http1.1" | "h1" | "http2" | "h2" |
"http3" | "h3"`) is unchanged; it already accepts both spellings.
- `zig:check` and the `bun-types` `tsc` test pass locally. The full
HTTP/3 test suite will run in CI.