Skip to content

Remove the .zig porting-reference sources - #32621

Merged
Jarred-Sumner merged 48 commits into
mainfrom
ciro/rm-zig-sources
Jun 25, 2026
Merged

Jarred-Sumner merged 48 commits into
mainfrom
ciro/rm-zig-sources

Conversation

@cirospaciari

@cirospaciari cirospaciari commented Jun 23, 2026 •

Copy link
Copy Markdown
Member

The Rust port is the only compiled implementation; the 1,270 .zig files under src/ have been kept alongside their .rs replacements purely as a behavioral reference and are not built (build.zig is gone, no Cargo build.rs or include_str! reads them). Drop them: 666k lines.

Codegen

  • generate-js2native.ts / replacements.ts / private.d.ts: the builtin-JS macros are renamed $zig()/$newZigFunction() -> $rust()/$newRustFunction() across every src/js/ call site, the exported C symbol prefix JS2Zig__* -> JS2Rust__*, and the emitted .d.ts union NativeFilenameZig -> NativeFilenameRust. resolveNativeFileId() for $rust() looks up a static 50-entry .rs-keyed rustIdentifierPaths table instead of scanning the filesystem; the resolved path is never opened but drives both the exported symbol name and the crate::... target in generated_js2native.rs. Unknown identifiers still fail codegen with a clear error. The two hand-exported dns.rs symbols are updated to the new prefix. The dead getJS2NativeZig() emitter is dropped.
  • Dead .zig output from codegen: bindgen.ts (GeneratedBindings.zig), bindgenv2/script.ts (bindgen_generated.zig + per-type), generate-classes.ts (ZigGeneratedClasses.zig), generate-node-errors.ts (ErrorCode.zig), cppbind.ts (cpp.zig), and bundle-modules.ts (GeneratedJS2Native.zig) all stop emitting their .zig outputs. Each already has an .rs/.cpp/.h sibling in the same ninja edge, so cargo/cxx dependency ordering is preserved. scripts/build/codegen.ts drops the matching declared outputs, zigFilesGeneratedIntoSrc, bindgenV2Zig, and emitCiInfo (whose only output was ci_info.zig; Rust uses the hand-maintained ci_info_generated module in runtime/cli/mod.rs). .gitignore drops the two in-src/ generated .zig entries.
  • bindgen.ts: drop the on-disk existence check for each *.bind.ts file's .zig sibling; the path is only used as a map key.
  • bake-codegen.ts: extract IncomingMessageId/MessageId from dev_server/mod.rs instead of DevServer.zig. PascalCase variants are snake_cased so generated.ts is byte-identical for the HMR client.
  • glob-sources.ts: drop the unused zig glob entry. Add src/runtime/bake/dev_server/mod.rs to bakeRuntime.paths so editing a MessageId discriminant re-runs bake-codegen on incremental builds.

Manual codegen scripts

  • src/css/properties/generate_properties.ts: deleted; properties_generated.rs is hand-maintained (its header already said so). The css-properties package.json entry is dropped.
  • src/css/values/color_via.ts: deleted; the committed color_generated.rs routes conversions through different intermediates than the script would produce, so the .rs is the source of truth. Header updated to "hand-maintained".
  • src/css/build-prefixes.js: emission rewritten to produce prefixes.rs / compat.rs / the Features bitflags! block in targets.rs, with rustfmt instead of zig fmt. allBrowsers (previously referenced but never defined) added. The committed .rs files are unchanged; the script is ready for the next caniuse refresh.
  • misctools/generate-add-completions.ts: ported to emit src/runtime/cli/add_completions.rs (FirstLetter enum, zstd-compressed blob via Bun.zstdCompressSync, per-letter INDEX table, Once<Table>-backed init/get_packages). Regenerated from add_completions.txt, so bun add completions are populated again instead of returning &[].
  • scripts/generate-perf-trace-events.sh: rewritten to scan .rs for both call shapes (bun_core::perf::trace("...") and bun_perf::trace(PerfEvent::X)), emit generated_perf_trace_events.h and the PerfEvent enum in generated_perf_trace_events.rs, and fail on zero matches.

Tests

  • test/internal/expect-call-counter.test.ts: reinstates the incrementExpectCallCounter coverage check over src/runtime/test_runner/expect/*.rs, accepting the shared helpers (matcher_prelude, unary_predicate_matcher!, run_string_affix_matcher, contain_matcher, numeric_ordering_matcher, mock_prologue) that call it internally. All 75 matchers satisfy it.
  • test/internal/ban-words.test.ts + ban-limits.json: deleted; the banned-words counts and the original per-matcher check were both defined over .zig sources that no longer exist.
  • zstd.test.ts: use parser.rs (~85 KB) as the large compression payload instead of the deleted parser.zig.
  • glob/stress.test.ts: scan src/**/*.rs instead of *.zig.

Docs

  • docs/project/bindgen.mdx: rewritten against the Rust workflow using bindgen_test.rs / fmt_jsc.rs as the worked examples (that file already says "this example should be kept in sync with bindgen's documentation").
  • CLAUDE.md, src/CLAUDE.md, scripts/build/CLAUDE.md, .claude/commands/upgrade-webkit.md, .claude/docs/landing-prs.md, scripts/build/codegen.ts: drop prose that described the .zig siblings or the removed sources.zig glob.
  • Per-subsystem docs (src/bundler/linker_context/README.md, src/event_loop/README.md, src/runtime/image/README.md, src/jsc/STREAMS.md, src/js/{CLAUDE,README}.md, src/jsc/bindings/v8/{CLAUDE,AGENTS}.md): repoint .zig filename references at their .rs replacements.

Dead tooling and config

  • scripts/longest.js, scripts/cleartrace{.ts,-impl.js}: deleted; longest.js hard-rejected non-.zig input and parsed Zig declaration syntax, cleartrace filtered Zig compiler output that cannot appear now that bun run watch runs cargo watch.
  • src/codegen/ci_info.ts: deleted; emitted only Zig.
  • src/clap/{zig.mod,gyro.zzz}: deleted; zigmod/gyro package manifests whose every declared source is removed here.
  • misctools/lldb/lldb_pretty_printers.py, misctools/gdb/zig_gdb_pretty_printers.py: deleted along with their init.lldb / .vscode/launch.json wiring; vendored Zig-language debug formatters that match nothing in a Rust binary.
  • .claude/skills/{implementing-jsc-classes-zig,zig-system-calls}/: replaced by Rust equivalents implementing-jsc-classes-rust and rust-system-calls (a -cpp sibling already exists for the former). .claude/hooks/post-edit-zig-format.js -> post-edit-format.js (prettier branch kept); pre-bash-zig-build.js -> pre-bash-guard.js. The GC skill points at src/jsc/JSRef.rs.
  • .vscode/settings.json: drop the // Zig block pointing at nonexistent vendor/zig/ and the [zig] formatter config.
  • .gitattributes, .dockerignore: drop *.zig / .zig-cache entries.
  • .github/workflows/format.yml, package.json: drop the Ban Words workflow step and banned script.
  • Source-comment references: repoint .zig paths in packages/bun-u{ws,sockets}/ headers, StringBuilderBinding.cpp, TopExceptionScopeBinding.cpp, PipeWriter.rs, StandaloneModuleGraph.rs, yaml.rs, comptime_string_map.rs, bundler/Cargo.toml, windows-shim/Cargo.toml, install.ps1, rust.ts, scripts/build/deps/{zstd,libarchive}.ts at their .rs replacements. External attribution URLs (github.com/.../*.zig) are left as-is.

How we know it works

  • bun bd links cleanly against the regenerated JS2Rust__* symbols; the hand-exported dns.rs symbols were updated to match.
  • hmr-runtime-client.ts bundles cleanly against the regenerated generated.ts; all four MessageId.* references it uses resolve to the same byte values.
  • The regenerated add_completions.rs compiles and the binary runs.
  • test/internal/expect-call-counter.test.ts passes against all 75 matchers.
  • No codegen script writes a .zig file anywhere; no ninja edge declares a .zig output; no .zig is tracked under src/ or misctools/.

@robobun

robobun commented Jun 23, 2026 •

Copy link
Copy Markdown
Collaborator
Updated 8:02 PM PT - Jun 24th, 2026

✅ @robobun, your commit 46fff1c914a350559ecb64d1c4bbb1d6dc7e98cf passed in Build #64573! 🎉


🧪   To try this PR locally:

bunx bun-pr 32621

That installs a local version of the PR into your bun-32621 executable, so you can run:

bun-32621 --bun

@coderabbitai

coderabbitai Bot commented Jun 23, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Removes the zig glob pattern from the build source enumeration script and strips all references to .zig sibling files as porting references from contributor documentation, including updates to build tooling comments, phase documentation, CI validation steps, and Zig-specific trace filtering scripts.

Changes

Remove .zig References from Build Tooling and Docs

Layer / File(s) Summary
Remove zig glob pattern and update build docs
scripts/glob-sources.ts, scripts/build/codegen.ts, scripts/build/CLAUDE.md, scripts/build/deps/libarchive.ts, scripts/build/deps/zstd.ts
The zig entry is removed from the patterns map in glob-sources.ts, eliminating the Sources.zig field and globAllSources() zig output. The codegen.ts header comment is trimmed to one line, and scripts/build/CLAUDE.md updates the globAllSources() snapshot to show .rs instead of .zig sources. Build dependency comments are updated to reference Rust source files: libarchive.ts references TarballStream.rs instead of .zig, and zstd.ts references lib.rs instead of zstd.zig.
Remove .zig sibling guidance from contributor and internal docs
CLAUDE.md, src/CLAUDE.md, .claude/commands/upgrade-webkit.md, .claude/docs/landing-prs.md
CLAUDE.md removes the .zig-as-porting-reference paragraph, drops .zig siblings from the "Verify semantics empirically" bullet, and removes the instruction against importing Zig-era conventions into Rust. src/CLAUDE.md removes the paragraph explaining why .zig siblings exist next to .rs files. Internal guides upgrade-webkit.md and landing-prs.md remove .zig-related parentheticals.
Remove ban-words validation and trace output filtering
.github/workflows/format.yml, package.json, scripts/cleartrace.ts
The Ban Words step is removed from the format workflow that invoked bun ./test/internal/ban-words.test.ts, and the corresponding banned npm script entry is removed from package.json. The scripts/cleartrace.ts script that filtered Zig compiler error messages from watch output is deleted.

Possibly related issues

  • oven-sh/bun#32210: The removal of .zig file references from build patterns and documentation enables the proposed decoupling of native bindings from requiring .zig files to exist on disk for codegen resolution.

Suggested reviewers

  • alii
  • Jarred-Sumner
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: removal of .zig files that serve as porting references, no longer needed since Rust is the only compiled implementation.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The PR description is thorough and covers both the change summary and verification, even though the headings differ from the template.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands.

The Rust port is the only compiled implementation; the 1,270 .zig files
under src/ have been kept alongside their .rs replacements purely as a
behavioral reference and are not built (build.zig is gone, no Cargo
build.rs or include_str! reads them). Drop them.

Collateral fixes so nothing points at the deleted files:

  - bake-codegen.ts: extract IncomingMessageId/MessageId from
    dev_server/mod.rs instead of DevServer.zig (PascalCase variants are
    snake_cased so generated.ts is unchanged for the HMR client). Fail
    loudly if an enum is missing or empty.
  - glob-sources.ts: drop the unused 'zig' glob entry.
  - test/internal/ban-words.test.ts + ban-limits.json: deleted — the
    banned-words counts and the per-matcher incrementExpectCallCounter
    check were both defined over .zig sources that no longer exist.
  - zstd.test.ts: use parser.rs as the large compression payload.
  - glob/stress.test.ts: scan src/**/*.rs instead of *.zig.
  - CLAUDE.md, src/CLAUDE.md, scripts/build/CLAUDE.md,
    scripts/build/codegen.ts: drop prose that described the .zig siblings
    or the removed sources.zig glob.

Not touched here (follow-ups):

  - src/css/build-prefixes.js still emits targets.zig/prefixes.zig/compat.zig
    and shells out to 'zig fmt'. The .rs outputs already exist and claim a
    '--rs' mode that the script does not implement; the script needs porting
    before the next caniuse refresh.
  - scripts/build/codegen.ts still generates a handful of .zig outputs into
    codegenDir / src/jsc/bindings (gitignored) that nothing consumes.
  - A Rust equivalent of the per-matcher incrementExpectCallCounter check.
@cirospaciari
cirospaciari force-pushed the ciro/rm-zig-sources branch from 71b23f4 to 495c6a7 Compare June 23, 2026 00:57
Comment thread scripts/glob-sources.ts
Comment thread CLAUDE.md
Comment thread scripts/build/codegen.ts Outdated
cirospaciari and others added 4 commits June 22, 2026 18:23
The \$zig() / \$newZigFunction() macro and bindgen both used the .zig
sibling path purely as an identifier (comment text, map key, dedup key)
and never opened the file; the existsSync was a sanity guard from when
the .zig sources were the implementation. With the .zig reference files
removed:

  - generate-js2native.ts: stop scanning src/ for .zig; for the "zig"
    call type return the filename identifier directly instead of
    resolving it against the (now empty) source list. NativeFilenameZig
    becomes string.
  - bindgen.ts: drop the per-.bind.ts existsSync of the .zig sibling.

Verified bindgen.ts and registerNativeCall("zig", "ffi.zig", ...) both
run to completion locally.
Both invoked test/internal/ban-words.test.ts, which is gone.
…README section

bunshell's broken-pipe-subproc test grepped src/js_parser/parser.zig
from cwd; with that file gone grep writes ENOENT to stderr and the
.stderr('') assertion fails. parser.rs is the same large file
zstd.test.ts now uses.
Comment thread scripts/build/codegen.ts Outdated
Comment thread CLAUDE.md
Comment thread src/CLAUDE.md
Comment thread scripts/glob-sources.ts
@alii

alii commented Jun 23, 2026

Copy link
Copy Markdown
Member

@robobun get this mergable

@robobun

robobun commented Jun 23, 2026 •

Copy link
Copy Markdown
Collaborator

All follow-ups and every review finding through 46fff1c addressed across 50+ iterations, including the three findings on Jarred's 962393f ($zig -> $rust rename). PR description re-synced to HEAD. cargo clippy and all build-rust lanes green on every recent build; the only CI red has been unrelated intermittent test flakes and the darwin-aarch64-26-5-1-1 agent's persistent artifact-download timeout, none of which touch code in this diff.

Every .md under src/, .claude/, and docs/ that this PR touched now greps clean for \bzig\b prose, ```zig fences, and jsc.* Zig-era type names. The diff is ready for human review. The darwin-26 lane can be retried in Buildkite directly or merged over.

robobun and others added 3 commits June 23, 2026 11:24
resolveNativeFileId() for $zig() now returns the absolute path each
identifier resolved to before the .zig sources were removed, via a
50-entry lookup table. rustTarget() and normalizeSymbolPathPrefix()
both depend on the directory component, so returning the bare macro
argument (24e728b1) caused every thunk in generated_js2native.rs to
reference a nonexistent crate::dispatch::js2native::* item and changed
the exported JS2Zig__* symbol names.

Verified generated_js2native.rs and GeneratedJS2Native.h are
byte-identical to what the previous directory scan produced.

Also drops two .claude/ doc references to the deleted .zig files.
Comment thread scripts/build/CLAUDE.md
Comment thread scripts/build/codegen.ts Outdated
- Delete scripts/longest.js: hard-rejects non-.zig input, parses Zig
  declaration syntax; now unconditionally dead with no callers.
- Delete scripts/cleartrace.ts + cleartrace-impl.js: filters Zig
  compiler output (logger.zig, @CompileError, vendor/zig/lib/std)
  that cannot appear now that "bun run watch" runs cargo.
- scripts/build/deps/{zstd,libarchive}.ts: repoint rationale comments
  at the .rs files that replaced the cited .zig sources.
- generate-js2native.ts: restore the NativeFilenameZig literal union
  from Object.keys(zigIdentifierPaths) so $zig()/$newZigFunction()
  keep IDE autocomplete and edit-time typo checking.
Comment thread package.json
Comment thread scripts/glob-sources.ts
bake-codegen.ts now reads src/runtime/bake/dev_server/mod.rs to derive
the MessageId/IncomingMessageId const-enums for the HMR client, but the
ninja edge only declared *.{ts,css} inputs. Editing a wire-protocol
discriminant in mod.rs would rebuild the server (via sources.rust)
without regenerating generated.ts/bake.client.js, leaving the client
with stale inlined opcodes on incremental builds.

Also drop the "css-properties" package.json script: it points at
src/css/properties/generate_properties.ts which writes
properties_generated.zig and runs vendor/zig/zig.exe fmt, neither of
which can succeed now. Same class as build-prefixes.js (follow-up).
Comment thread scripts/build/codegen.ts Outdated
Comment thread package.json
Comment thread scripts/build/CLAUDE.md
Comment thread src/CLAUDE.md
robobun and others added 3 commits June 23, 2026 13:14
Dead files this PR orphans:
- src/clap/{zig.mod,gyro.zzz}: zigmod/gyro package manifests whose
  every declared source (clap.zig, clap/*.zig) is deleted here.
- misctools/lldb/lldb_pretty_printers.py + init.lldb wiring: vendored
  ziglang/zig lldb formatters for Zig-language debug info the binary
  no longer contains.
- misctools/gdb/zig_gdb_pretty_printers.py + .vscode/launch.json
  source line: same, for gdb/rr.
- .vscode/settings.json: drop the "// Zig" block pointing at
  nonexistent vendor/zig/ and a [zig] formatter for zero files.

Internal docs: repoint .zig filenames at their .rs replacements in
src/bundler/linker_context/README.md, src/event_loop/README.md,
src/runtime/image/README.md, src/jsc/STREAMS.md, src/js/{CLAUDE,README}.md,
and src/jsc/bindings/v8/{CLAUDE,AGENTS}.md (napi.zig -> napi_body.rs).
Every rewritten path verified to exist on disk.
Comment thread .claude/commands/upgrade-webkit.md
@Jarred-Sumner

Copy link
Copy Markdown
Collaborator

@robobun please fix all the follow-ups and then update the PR body. All of the follow-ups belong in this PR.

@robobun

robobun commented Jun 23, 2026 •

Copy link
Copy Markdown
Collaborator

All seven workstreams below complete as of a23032c. PR body updated to match.

1. Dead .zig codegen emitters (done): dropped getJS2NativeZig from generate-js2native.ts; dropped .zig writers from generate-classes.ts, generate-node-errors.ts, cppbind.ts; dropped the matching declared outputs + zigFilesGeneratedIntoSrc + bindgenV2Zig + emitCiInfo from scripts/build/codegen.ts; deleted src/codegen/ci_info.ts. The bindgen.ts / bindgenv2 zig CodeWriters are left in place (closed recursion; see status comment above for rationale).

2. Manual codegen scripts → Rust output (done):

  • src/css/properties/generate_properties.ts: deleted (dead).
  • src/css/values/color_via.ts: deleted (dead; color_generated.rs is hand-maintained).
  • src/css/build-prefixes.js: now emits prefixes.rs / compat.rs and the Features bitflags block in targets.rs; .zig emission removed. Verified byte-identical to the committed .rs files.
  • misctools/generate-add-completions.ts: now emits src/runtime/cli/add_completions.rs (zstd-compressed blob, FirstLetter enum, per-letter INDEX, Once-backed get_packages).

3. scripts/generate-perf-trace-events.sh (done): rewritten to scan .rs for both bun_core::perf::trace("...") and bun_perf::trace(PerfEvent::X) call shapes, emit .h + generated_perf_trace_events.rs; .zig output dropped. Verified round-trips the current enum.

4. docs/project/bindgen.mdx (done): rewritten against the Rust workflow using bindgen_test.bind.ts / bindgen_test.rs as the worked example.

5. incrementExpectCallCounter test (done): reinstated as test/internal/expect-call-counter.test.ts.

6. .claude/ cleanup (done): deleted skills/implementing-jsc-classes-zig/ and skills/zig-system-calls/; renamed hooks/post-edit-zig-format.js → post-edit-format.js (prettier branch kept) and pre-bash-zig-build.js → pre-bash-guard.js; repointed skills/javascriptcore-garbage-collector/SKILL.md at JSRef.rs.

7. Source-comment references (done): repointed ~20 .zig paths in packages/bun-u{ws,sockets}/, src/**/*.{rs,cpp,md}, scripts/build/rust.ts, install.ps1; dropped *.zig / .zig-cache from .gitattributes / .dockerignore. External attribution URLs and $zig(...) codegen keys left as-is.

cirospaciari and others added 2 commits June 23, 2026 14:51
Dead .zig codegen emitters (nothing consumes these outputs):
- bundle-modules.ts / generate-js2native.ts: drop getJS2NativeZig.
- bindgen.ts: stop writing GeneratedBindings.zig.
- bindgenv2/script.ts: stop listing/writing bindgen_generated.zig.
- generate-classes.ts: drop ZigGeneratedClasses.zig write and header.
- generate-node-errors.ts: drop ErrorCode.zig accumulation and write.
- cppbind.ts: drop cpp.zig write.
- scripts/build/codegen.ts: drop all .zig declared outputs,
  zigFilesGeneratedIntoSrc, bindgenV2Zig, emitCiInfo (ci_info.ts
  deleted; Rust uses hand-maintained ci_info_generated).
- .gitignore: drop the matching entries.

Manual codegen scripts:
- generate_properties.ts: deleted; properties_generated.rs header
  already said "hand-maintained, does not write this file".
- color_via.ts: deleted; the committed color_generated.rs routes
  through different intermediates than the script would produce, so
  the .rs is the source of truth. Header updated.
- build-prefixes.js: emission rewritten to produce prefixes.rs /
  compat.rs / the Features bitflags block in targets.rs, with
  rustfmt instead of zig fmt. allBrowsers (previously undefined)
  added. The committed .rs files are unchanged; the script is ready
  for the next caniuse refresh.
- generate-add-completions.ts: ported to emit add_completions.rs
  (FirstLetter enum, zstd-compressed blob, per-letter INDEX,
  Once<Table> init/get_packages). Regenerated from
  add_completions.txt; bun add completions now populated again.

generate-perf-trace-events.sh: rewritten to scan .rs for both
bun_core::perf::trace("...") and bun_perf::trace(PerfEvent::X),
emit generated_perf_trace_events.h and the PerfEvent enum in
generated_perf_trace_events.rs, and fail loudly on zero matches.

docs/project/bindgen.mdx: rewritten against the Rust workflow using
bindgen_test.rs / fmt_jsc.rs as the worked examples.

test/internal/expect-call-counter.test.ts: reinstates the
increment_expect_call_counter coverage check over
src/runtime/test_runner/expect/*.rs, accepting the shared helpers
(matcher_prelude, unary_predicate_matcher!, etc.) that call it.

.claude/: delete skills/implementing-jsc-classes-zig and
skills/zig-system-calls (workflows that cannot be followed); delete
hooks/post-edit-zig-format.js and its settings wiring; point the GC
skill at src/jsc/JSRef.rs.

Comment/config references: repoint .zig paths in bun-uws/bun-usockets
headers, StringBuilderBinding.cpp, TopExceptionScopeBinding.cpp,
PipeWriter.rs, StandaloneModuleGraph.rs, yaml.rs,
comptime_string_map.rs, bundler/Cargo.toml, windows-shim/Cargo.toml,
install.ps1, rust.ts; drop *.zig / .zig-cache from .gitattributes and
.dockerignore.

bun bd links cleanly.
robobun added a commit that referenced this pull request Jun 29, 2026
The Zig sources were removed in #32621 and the Rust port is the only
implementation, but the README, the docs site, the VS Code extension
README, and the Bun.password JSDoc in bun-types still said Bun is
written in Zig.

Update those claims, fix the LICENSE relink instructions (which told
people to run `make jsc` and `zig build`), and remove a few
developer-facing leftovers: the dead zig problemMatcher in
.vscode/tasks.json, a stale .zig path, and a comment describing a Zig
build flag that no longer exists.

Fixes #31233
alii pushed a commit that referenced this pull request Jun 29, 2026
Fixes #31233

### What does this PR do?

#32621 removed the Zig sources; the Rust port is the only
implementation. The README, the docs site, and a couple of published
packages still describe Bun as written in Zig (#31233 reports the README
one). This updates them. Nothing in this PR reaches the compiler: it is
markdown, mdx, JSDoc, editor config, and a build-script comment.

**User-facing**

- `README.md`, `docs/index.mdx`, `packages/bun-vscode/README.md`: "It's
written in Zig and powered by JavaScriptCore" now says Rust.
- `docs/runtime/index.mdx`, `docs/bundler/esbuild.mdx`,
`docs/runtime/{shell,redis,json5,yaml,markdown}.mdx`: "written in Zig"
and "Zig-based" claims, each checked against the actual implementation
(`src/runtime/shell/`, `src/runtime/valkey_jsc/`,
`src/parsers/{json5,yaml}.rs`, `src/md/`).
- `docs/bundler/css.mdx`: the CSS bundler was described as "a direct
Rust → Zig port of LightningCSS", now "a direct port of LightningCSS".
- `docs/bundler/html-static.mdx`: "58,000 lines of Zig" becomes "70,000
lines of Rust" (`src/css/**/*.rs` is 71.7k lines today).
- `docs/runtime/utils.mdx`: the `Bun.stringWidth` SIMD implementation
lives in `src/jsc/bindings/stringWidth.cpp`, so this one says "native
code" rather than claiming Rust.
- `docs/runtime/ffi.mdx`: the C++ example was compiled with `zig
build-lib add.cpp`; it now shows `clang++` for Linux and macOS. The Zig
FFI example itself stays, since calling a Zig shared library through
`bun:ffi` is unrelated to Bun's implementation language.
- `packages/bun-types/bun.d.ts`: the `Bun.password` JSDoc credited the
Zig standard library. The implementation routes to the `rust-argon2` and
`bcrypt` crates (`src/runtime/crypto/pwhash.rs`), so it now says that.
- `LICENSE.md` and `docs/project/license.mdx` still told people to
relink WebKit with `git submodule update`, `make jsc`, and `zig build`,
none of which exist anymore. The steps now match
`docs/project/contributing.mdx`: clone the WebKit fork into
`vendor/WebKit`, check out `WEBKIT_VERSION`, run `bun run build:local`.
The esbuild credit is now "a port of esbuild".

**Developer-facing**

- `.vscode/tasks.json`: the "Build Bun" task had a zig-owner
problemMatcher for `file:line:col: error:` output. There is no Zig
compiler in the build, and the clang matcher next to it handles the same
single-line format, so the dead matcher is removed.
- `misctools/lldb/README.md`, `scripts/build/deps/nodejs-headers.ts`,
`test/js/web/fetch/H2_TEST_PORT_PLAN.md`: internal docs that described
`ZigString` as "the Zig string type", a Zig build flag that no longer
exists, and a deleted `.zig` path.

**Intentionally not changed**

- Identifiers that still exist in the code (`Zig::GlobalObject`,
`ZigString`, `$ZigGeneratedClasses`, `zig_mutex_t`). #31822 is the
rename pass for those.
- Comments inside compiled sources (the `src/codegen/*.ts` "written in
Zig" docblocks, the `packages/bun-usockets` header, a few `src/js`
notes). Those are code changes, not docs, and they fit better with the
identifier rename than with this prose pass.
- The `bun:ffi` docs listing Zig among the C ABI languages, and the Zig
FFI example.
- Comments that are deliberately historical: Cargo.toml rationale notes,
`bench/snippets/escapeHTML.mjs`, tests that explain a Zig-era bug.
- External links into other projects' `.zig` files, such as the
Tigerbeetle row in the license table.
- `process.versions.zig` is still exposed at runtime with a pinned
historical hash (`BunProcess.cpp` and
`scripts/build/depVersionsHeader.ts`). Removing a `process.versions` key
is a behavior change, not a docs fix, so it is left for a separate
decision.

### How did you verify your code works?

- This PR changes prose only; no compiled source is touched, so there is
no runtime behavior to regression-test.
- Every "written in Rust" claim was checked against the implementation
it describes before editing (paths above).
- `bun test test/integration/bun-types/bun-types.test.ts` passes with
the `bun.d.ts` edit.
- The docs preview deployment renders the changed pages.
robobun added a commit that referenced this pull request Jul 5, 2026
The .zig porting-reference sources were removed on main (#32621), so
$newZigFunction("event_loop.zig", ...) no longer resolves. Switch to
$newRustFunction("event_loop.rs", ...); the dispatch re-export and the
js_event_loop_utilization host fn are already in place.
robobun added a commit that referenced this pull request Jul 10, 2026
The .zig porting-reference sources were removed on main (#32621), so
$newZigFunction("event_loop.zig", ...) no longer resolves. Switch to
$newRustFunction("event_loop.rs", ...); the dispatch re-export and the
js_event_loop_utilization host fn are already in place.
dylan-conway pushed a commit that referenced this pull request Jul 24, 2026
…35327)

### What does this PR do?

The registry/token env-var scan loops in `Options::load`
(`src/install/PackageManager/PackageManagerOptions.rs`) carried a
`did_set` flag with an `if !did_set` guard in place of `break`. This was
a workaround for a Zig stage1 compiler bug where `break` inside `inline
for` was broken, ported verbatim into the Rust rewrite along with its
explanatory comment:

```rust
self.scope.token = registry_.into();
did_set = true;
// stage1 bug: break inside inline is broken
// break :load_registry;
```

The Zig sources were removed in #32621 and the stage1 compiler no longer
exists. In Rust this is just a plain `for` loop, so use `break` directly
and drop:

- the `did_set` flag and `if !did_set` wrapper (both loops)
- the dead `// break :load_registry;` Zig-syntax comment
- the `// load_registry:` label comment
- the two `// was \`inline for\`; homogeneous elements -> plain for.`
porting notes

### Behavior

**No observable change.** The `if !did_set` guard already ensured the
first matching env var wins; this PR just expresses that with `break`.
Verified empirically against the released binary:

```
BUN_CONFIG_TOKEN=a NPM_CONFIG_TOKEN=b npm_config_token=c bun install
  -> Authorization: Bearer a
```

### Tests

Added to `test/cli/install/bun-install-registry.test.ts` to lock in the
priority order (previously untested):

- `BUN_CONFIG_TOKEN` wins over `NPM_CONFIG_TOKEN` and `npm_config_token`
- empty `BUN_CONFIG_TOKEN` falls through to `NPM_CONFIG_TOKEN`
- `BUN_CONFIG_REGISTRY` wins over `NPM_CONFIG_REGISTRY` /
`npm_config_registry`

These pass on the released binary as well; they exist to pin the
refactor and guard against future changes to the key ordering.

Related: #34170 touches the same block for a different concern (bunfig
vs. env-var precedence); whichever lands second will need a small
rebase.

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

---

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

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

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
robobun added a commit that referenced this pull request Aug 14, 2026
Re-ports the fix onto the Rust Request/fetch (the Zig sources were
removed in #32621). Same behavior as the original PR:

- Add `integrity`/`referrer` OwnedStringCell fields and a `keepalive`
  bit in Flags (widened 4→5 bytes; assert_ffi_layout updated). Parse
  them in construct_into, copy in clone_into and the Request-merge
  path, deref in finalize_without_deinit, count in memory_cost and
  calculate_estimated_byte_size.
- getReferrer returns the spec tri-state ("about:client" default,
  "" for the no-referrer sentinel, else the serialized URL);
  getIntegrity returns the stored value; new getKeepalive wired via
  response.classes.ts.
- Fetch spec step 12: a non-empty init resets referrer to "client"
  before init.referrer is read. Detected via an up-front WebIDL
  member-presence probe (matches undici's RequestInit key set), gated
  to the base iteration by loop index (handles aliased `new Request(
  req, req)`), and re-applied in the generic block so Request
  subclasses / structure-mutated bases (which bypass as_direct) don't
  leak the base referrer.
- fetch.rs: skip Request objects (via `.as_`, subclass-aware) in the
  keepalive option extractor so the new spec accessor (default false)
  doesn't disable HTTP connection pooling.

Tests ported unchanged: 20 in request.test.ts, 3 parameterized
pooling cases in fetch-args.test.ts. All pass; referrer matrix
matches Node 24.
robobun added a commit that referenced this pull request Aug 15, 2026
The .zig porting-reference sources were removed in #32621, so the
comment's reference to Zig's `?[]const u8` semantics and the camelCase
function name no longer resolve in the tree. Use the real snake_case
Rust function name and language-agnostic phrasing matching the source
comment.
robobun added a commit that referenced this pull request Aug 22, 2026
Re-ports the fix onto the Rust Request/fetch (the Zig sources were
removed in #32621). Same behavior as the original PR:

- Add `integrity`/`referrer` OwnedStringCell fields and a `keepalive`
  bit in Flags (widened 4→5 bytes; assert_ffi_layout updated). Parse
  them in construct_into, copy in clone_into and the Request-merge
  path, deref in finalize_without_deinit, count in memory_cost and
  calculate_estimated_byte_size.
- getReferrer returns the spec tri-state ("about:client" default,
  "" for the no-referrer sentinel, else the serialized URL);
  getIntegrity returns the stored value; new getKeepalive wired via
  response.classes.ts.
- Fetch spec step 12: a non-empty init resets referrer to "client"
  before init.referrer is read. Detected via an up-front WebIDL
  member-presence probe (matches undici's RequestInit key set), gated
  to the base iteration by loop index (handles aliased `new Request(
  req, req)`), and re-applied in the generic block so Request
  subclasses / structure-mutated bases (which bypass as_direct) don't
  leak the base referrer.
- fetch.rs: skip Request objects (via `.as_`, subclass-aware) in the
  keepalive option extractor so the new spec accessor (default false)
  doesn't disable HTTP connection pooling.

Tests ported unchanged: 20 in request.test.ts, 3 parameterized
pooling cases in fetch-args.test.ts. All pass; referrer matrix
matches Node 24.
robobun added a commit that referenced this pull request Aug 24, 2026
Re-ports the fix onto the Rust Request/fetch (the Zig sources were
removed in #32621). Same behavior as the original PR:

- Add `integrity`/`referrer` OwnedStringCell fields and a `keepalive`
  bit in Flags (widened 4→5 bytes; assert_ffi_layout updated). Parse
  them in construct_into, copy in clone_into and the Request-merge
  path, deref in finalize_without_deinit, count in memory_cost and
  calculate_estimated_byte_size.
- getReferrer returns the spec tri-state ("about:client" default,
  "" for the no-referrer sentinel, else the serialized URL);
  getIntegrity returns the stored value; new getKeepalive wired via
  response.classes.ts.
- Fetch spec step 12: a non-empty init resets referrer to "client"
  before init.referrer is read. Detected via an up-front WebIDL
  member-presence probe (matches undici's RequestInit key set), gated
  to the base iteration by loop index (handles aliased `new Request(
  req, req)`), and re-applied in the generic block so Request
  subclasses / structure-mutated bases (which bypass as_direct) don't
  leak the base referrer.
- fetch.rs: skip Request objects (via `.as_`, subclass-aware) in the
  keepalive option extractor so the new spec accessor (default false)
  doesn't disable HTTP connection pooling.

Tests ported unchanged: 20 in request.test.ts, 3 parameterized
pooling cases in fetch-args.test.ts. All pass; referrer matrix
matches Node 24.
robobun added a commit that referenced this pull request Aug 24, 2026
Re-ports the fix onto the Rust Request/fetch (the Zig sources were
removed in #32621). Same behavior as the original PR:

- Add `integrity`/`referrer` OwnedStringCell fields and a `keepalive`
  bit in Flags (widened 4→5 bytes; assert_ffi_layout updated). Parse
  them in construct_into, copy in clone_into and the Request-merge
  path, deref in finalize_without_deinit, count in memory_cost and
  calculate_estimated_byte_size.
- getReferrer returns the spec tri-state ("about:client" default,
  "" for the no-referrer sentinel, else the serialized URL);
  getIntegrity returns the stored value; new getKeepalive wired via
  response.classes.ts.
- Fetch spec step 12: a non-empty init resets referrer to "client"
  before init.referrer is read. Detected via an up-front WebIDL
  member-presence probe (matches undici's RequestInit key set), gated
  to the base iteration by loop index (handles aliased `new Request(
  req, req)`), and re-applied in the generic block so Request
  subclasses / structure-mutated bases (which bypass as_direct) don't
  leak the base referrer.
- fetch.rs: skip Request objects (via `.as_`, subclass-aware) in the
  keepalive option extractor so the new spec accessor (default false)
  doesn't disable HTTP connection pooling.

Tests ported unchanged: 20 in request.test.ts, 3 parameterized
pooling cases in fetch-args.test.ts. All pass; referrer matrix
matches Node 24.
robobun added a commit that referenced this pull request Aug 25, 2026
Re-ports the fix onto the Rust Request/fetch (the Zig sources were
removed in #32621). Same behavior as the original PR:

- Add `integrity`/`referrer` OwnedStringCell fields and a `keepalive`
  bit in Flags (widened 4→5 bytes; assert_ffi_layout updated). Parse
  them in construct_into, copy in clone_into and the Request-merge
  path, deref in finalize_without_deinit, count in memory_cost and
  calculate_estimated_byte_size.
- getReferrer returns the spec tri-state ("about:client" default,
  "" for the no-referrer sentinel, else the serialized URL);
  getIntegrity returns the stored value; new getKeepalive wired via
  response.classes.ts.
- Fetch spec step 12: a non-empty init resets referrer to "client"
  before init.referrer is read. Detected via an up-front WebIDL
  member-presence probe (matches undici's RequestInit key set), gated
  to the base iteration by loop index (handles aliased `new Request(
  req, req)`), and re-applied in the generic block so Request
  subclasses / structure-mutated bases (which bypass as_direct) don't
  leak the base referrer.
- fetch.rs: skip Request objects (via `.as_`, subclass-aware) in the
  keepalive option extractor so the new spec accessor (default false)
  doesn't disable HTTP connection pooling.

Tests ported unchanged: 20 in request.test.ts, 3 parameterized
pooling cases in fetch-args.test.ts. All pass; referrer matrix
matches Node 24.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants