Skip to content

undici: remove polyfill, resolve to real npm package - #30561

Closed
galenzo17 wants to merge 7 commits into
oven-sh:mainfrom
galenzo17:remove-undici-polyfill
Closed

galenzo17 wants to merge 7 commits into
oven-sh:mainfrom
galenzo17:remove-undici-polyfill

Conversation

@galenzo17

Copy link
Copy Markdown

What does this PR do?

Removes Bun's built-in undici polyfill so that require("undici") / import from "undici" resolves to the actual npm-installed package instead of Bun's incomplete stub.

The polyfill lacks critical features (Agent.compose(), real interceptors, proper Dispatcher methods) causing breakage in packages like payload, @distube/ytdl-core, and http-cookie-agent. See also #20022.

Changes:

  • Remove undici from HardcodedModule enum, module map, and alias entries (including next/dist/compiled/undici)
  • Remove "undici" from isBuiltinModule and builtinModuleNames lists
  • Delete polyfill source: src/js/thirdparty/undici.js, src/jsc/bindings/Undici.{cpp,h}
  • Delete polyfill tests: test/js/first_party/undici/
  • Update fuzzy-wuzzy.test.ts builtin module list

After this change, require("undici") behaves like Node.js: it resolves to the npm package if installed, or throws "Cannot find module" otherwise.

Fixes #17799

How did you verify your code works?

  • Verified no dangling references to deleted files (createUndiciInternalBinding, Undici.h, undici.js) across src/ and test/
  • Verified no remaining require("undici") / import from "undici" in test files
  • Follows the same pattern as the detect-libc polyfill removal (PR js: no longer provide our own 'detect-libc' #18138)
  • Build system (codegen, glob-sources) auto-discovers files, so deletions are handled automatically

Bun's undici polyfill intercepts all `require("undici")` calls and
returns an incomplete stub implementation. This causes real-world
breakage because the polyfill lacks critical features like
`Agent.compose()`, real interceptors, and proper Dispatcher methods.

Remove the hardcoded module interception so that `require("undici")`
resolves to the actual npm-installed undici package, matching Node.js
behavior.

Fixes oven-sh#17799

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@coderabbitai

coderabbitai Bot commented May 12, 2026 •

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: a954e9db-a1e2-4e3c-9a4d-a50e737704fa

📥 Commits

Reviewing files that changed from the base of the PR and between f4342c9 and 79d20cf.

⛔ Files ignored due to path filters (1)
  • test/bun.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • test/js/first_party/undici/undici.test.ts
  • test/package.json

Walkthrough

This PR removes Bun's bundled undici implementation: the JS compatibility layer, native JSC bindings, builtin/alias registrations, and related tests; test fixtures and the undici dev dependency version were updated accordingly.

Changes

Undici polyfill removal

Layer / File(s) Summary
JavaScript polyfill removal
src/js/thirdparty/undici.js
Removed the entire JS compatibility/polyfill module (previously exported moduleExports default and many named exports: request, Agent, Client, Pool, Headers, Request, Response, FormData, File, interceptors, errors, helpers, and stubs).
Native binding removal
src/jsc/bindings/Undici.h, src/jsc/bindings/Undici.cpp
Deleted the header and C++ implementation that provided createUndiciInternalBinding(Zig::GlobalObject*) and the native wiring exposing undici-related constructors/events to JS.
Builtin module registry updates
src/jsc/bindings/isBuiltinModule.cpp, src/jsc/modules/NodeModuleModule.cpp
Removed the "undici" entry from builtin module name lists used for module-resolution and builtin detection.
Hardcoded builtins and alias cleanup
src/resolve_builtins/HardcodedModule.zig
Removed HardcodedModule.undici enum variant and compile-time alias mappings for "undici" and next/dist/compiled/undici.
Tests and test config changes
test/js/first_party/undici/undici-primordials.test.ts, test/js/first_party/undici/undici.test.ts, test/js/bun/util/fuzzy-wuzzy.test.ts, test/package.json
Deleted undici-primordials.test.ts; replaced undici.test.ts with an integration-style suite backed by a local Bun.serve server; removed "undici" and added "process" in fuzzy-wuzzy modules list; bumped test package.json undici version to ^6.21.3.
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'undici: remove polyfill, resolve to real npm package' clearly and concisely describes the main change: removing Bun's built-in undici polyfill so imports resolve to the npm package instead.
Description check ✅ Passed The PR description is comprehensive, covering what the PR does, specific changes made, rationale, and verification steps. Both required template sections are well-filled with substantive content.
Linked Issues check ✅ Passed The PR fully addresses the objectives in issue #17799: removes the polyfill from all identified locations (HardcodedModule, isBuiltinModule, test files, binding/source files), ensuring require/import resolves to the npm package with correct APIs and behavior.
Out of Scope Changes check ✅ Passed All changes are directly in scope: removals of undici polyfill files, updates to builtin module lists, test file updates, and dependency version bump. No unrelated code modifications are present.

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

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prob should replace it with at very least a very extensive integration test to prove undici works well in bun (and doesn't get regressed)

also a good way to judge the compatibility

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, thanks! Will replace with comprehensive integration tests for the real undici package.

@galenzo17

Copy link
Copy Markdown
Author

Verified locally with a debug build.

▎ Before — polyfill intercepts the import, isBuiltin returns true,
and Agent.compose is undefined.

▎ After — real undici resolves from npm, isBuiltin returns false,
and Agent.compose is available as function.

▎ Screenshots attached. Happy to address any feedback.
image

image

galenzo17 added 2 commits May 12, 2026 13:10
Replace deleted polyfill tests with integration tests for the real
undici npm package. Upgrade undici from 5.20.0 to ^6.21.0 to cover
Dispatcher.compose(), interceptors, MockAgent, and other APIs that
the old polyfill was missing.
@galenzo17

Copy link
Copy Markdown
Author

Updated undici from 5.20.0 to 6.21.3 in test/package.json — v5 doesn't have Dispatcher.compose() or the interceptors API, which are the exact features that motivated removing the polyfill (#17799). Testing against v5 would miss the whole point.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/js/first_party/undici/undici.test.ts`:
- Around line 332-340: The test should be converted to an async test and the
cleanup calls awaited to avoid races: change the spec to be async and replace
the synchronous Agent.close() and Client.close() calls with await agent.close()
and await client.close(); keep the same assertions for Agent.compose and
Client.compose to locate the code (Agent, Client, compose, close).
- Line 1: Replace the runtime require("module") usage with a module-scope import
for isBuiltin: add an import { isBuiltin } from "module" at the top of the file
and remove the dynamic require call where isBuiltin is obtained, ensuring all
references in the test (e.g., any uses of isBuiltin in the undici.test.ts suite)
use the statically imported symbol instead.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: d7ef0368-880f-4422-836b-64c1f67d646b

📥 Commits

Reviewing files that changed from the base of the PR and between 4b66a0b and 33d92db.

⛔ Files ignored due to path filters (1)
  • test/bun.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • test/js/first_party/undici/undici.test.ts
  • test/package.json

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/js/first_party/undici/undici.test.ts`:
- Around line 332-340: The test calls the async undici close() on Agent and
Client without awaiting, which can leave cleanup unresolved; make the test async
and await both agent.close() and client.close() (or return/await their promises)
so Agent.close() and Client.close() are properly awaited after asserting
compose() exists.
- Around line 95-97: The test uses a dynamic import inside the spec: `const
undici = await import("undici");`—replace that with a module-scope import so the
test validates API presence rather than dynamic loading. Add a top-of-file
module import (e.g., import * as undici from "undici";) and remove the in-test
await import; keep the rest of the "exports all expected top-level APIs" test
using the `undici` symbol unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: ebc0f905-80a4-43ab-b40a-78134e5ece20

📥 Commits

Reviewing files that changed from the base of the PR and between 4b66a0b and f4342c9.

⛔ Files ignored due to path filters (1)
  • test/bun.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • test/js/first_party/undici/undici.test.ts
  • test/package.json

- Replace dynamic import/require with module-scope imports
- Import isBuiltin from node:module instead of require("module")
- Await agent.close() and client.close() in compose test
@galenzo17
galenzo17 requested a review from RiskyMH May 13, 2026 13:44
galenzo17 and others added 3 commits May 14, 2026 19:59
The Rust rewrite ported the module registry from Zig to Rust but
kept undici registered as a hardcoded module. Remove the enum
variant, phf map entry, alias table entry, and Next.js alias so
that require("undici") resolves to the real npm package.
@raphaelboudreault

Copy link
Copy Markdown

Will this be merged soon? This creates problem on our side for using cyclonedx with bun. Thanks a lot!

@robobun

robobun commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

Thank you for this work, @galenzo17, and for the integration suite you added after the first review. Sorry that it sat without a clear answer for so long.

The team is taking the approach in #36102 for this problem. Bare undici resolves to the installed package, and the built-in shim stays only as a fallback when the package is not installed. See the maintainer note on #36098: #36098 (comment). That shape keeps require("undici") working for projects that never install the package, and it keeps the next/dist/compiled/undici alias.

This branch also predates the Rust port of the resolver tables (src/resolve_builtins/HardcodedModule.zig no longer exists on main), so it conflicts with main and no longer applies as written.

Your tests were useful. I ran the suite from this PR against the real undici 6.21.3 under Bun 1.4.3: 32 of 33 tests pass (request(), Client, Pool, Agent, compose() with interceptors, MockAgent, errors, cookie and MIME helpers). The one failure is isBuiltin("undici"), which #36102 changes to false. I recorded that on #36102 (#36102 (comment)) so the suite can be carried over with a Co-authored-by credit to you when the test tree's undici pin moves to 6.x.

Closing this in favor of #36102. You are welcome to review it or build on it. If you think full removal of the shim is still the better call, say so there or on #17799 and this can be reopened.

@robobun robobun closed this Sep 9, 2026
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.

Remove the undici polyfill

4 participants