Skip to content

fix(runtime): stub node:/bun: built-ins in dev module server (#2315)#2318

Merged
viniciusdacal merged 3 commits into
mainfrom
viniciusdacal/fix-runtime-builtins
Apr 5, 2026
Merged

fix(runtime): stub node:/bun: built-ins in dev module server (#2315)#2318
viniciusdacal merged 3 commits into
mainfrom
viniciusdacal/fix-runtime-builtins

Conversation

@viniciusdacal
Copy link
Copy Markdown
Contributor

Summary

  • The dev module server now recognizes node:* and bun:* specifiers as runtime built-ins and returns empty ES module stubs instead of attempting to auto-install them from npm
  • The import rewriter short-circuits these specifiers to avoid unnecessary filesystem resolution
  • Stubs include console.warn() so developers know imports were stubbed for the browser
  • Comment injection prevention via // line comments and specifier sanitization

Root Cause

When @vertz/db (or any server-side package) is transitively pulled into the client bundle, its top-level import { ... } from "node:fs/promises" gets rewritten to /@deps/node:fs/promises. The module server's handle_deps_request() had no check for built-in modules, so it:

  1. Failed to find them in node_modules/
  2. Attempted auto-install from npm registry
  3. npm returned 404 → "Auto-install failed" error overlay

Changes

File Change
native/vtz/src/server/module_server.rs is_runtime_builtin() + runtime_builtin_stub() helpers, early return in handle_deps_request()
native/vtz/src/compiler/import_rewriter.rs Early return for node:/bun: in rewrite_specifier_inner()

Public API Changes

None — internal runtime behavior only.

Test plan

  • test_handle_deps_request_node_builtin_returns_stubnode:fs returns 200 with stub
  • test_handle_deps_request_node_builtin_subpath_returns_stubnode:fs/promises returns 200
  • test_handle_deps_request_bun_builtin_returns_stubbun:sqlite returns 200 with console.warn + export default
  • test_handle_deps_request_node_crypto_returns_stubnode:crypto returns 200
  • test_handle_deps_request_node_module_returns_stubnode:module returns 200
  • test_handle_deps_request_regular_package_still_404 — non-builtins still 404
  • test_handle_deps_request_builtin_stub_no_comment_injection — crafted node:*/alert(1)// does not execute
  • test_is_runtime_builtin_positive / test_is_runtime_builtin_negative — predicate unit tests
  • Import rewriter tests for node:*, bun:*, subpaths, and full-code integration
  • Rust quality gates: cargo test --all && cargo clippy --release -- -D warnings && cargo fmt --check

Closes #2315

🤖 Generated with Claude Code

viniciusdacal and others added 3 commits April 5, 2026 00:56
The dev module server tried to auto-install node:* and bun:* built-in
modules from npm when the browser requested them via /@deps/. These are
server-only modules that should never be resolved from the registry.

- Add is_runtime_builtin() check in handle_deps_request() to return
  empty ES module stubs for node:* and bun:* specifiers
- Short-circuit import rewriter for node:/bun: prefixes to skip
  unnecessary filesystem resolution

Closes #2315

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…on, tests

- Add console.warn to stub so devs know imports were stubbed (#2315)
- Switch from /* */ to // comments to prevent comment injection
- Add sanitization for specifier in JS string literal
- Add injection attack test and is_runtime_builtin unit tests
- Write review to reviews/fix-runtime-builtins/

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@viniciusdacal viniciusdacal merged commit 13cebc3 into main Apr 5, 2026
7 checks passed
This was referenced Apr 5, 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.

@vertz/db leaks server-only built-ins (bun:sqlite, node:fs, node:path, node:crypto) into the client bundle

1 participant