Skip to content

[WIP] Rendering API React framework implementation - #22504

Closed
alii wants to merge 364 commits into
mainfrom
ali/react
Closed

alii wants to merge 364 commits into
mainfrom
ali/react

Conversation

@alii

@alii alii commented Sep 8, 2025 •

Copy link
Copy Markdown
Member

What does this PR do?

wip

How did you verify your code works?

wip

@robobun

robobun commented Sep 8, 2025 •

Copy link
Copy Markdown
Collaborator
Updated 8:53 AM PT - Nov 4th, 2025

❌ @alii, your commit 6e3ee65 has 2 failures in Build #30934 (All Failures):


🧪   To try this PR locally:

bunx bun-pr 22504

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

bun-22504 --bun

@alii
alii marked this pull request as ready for review September 8, 2025 21:06
@alii
alii marked this pull request as draft September 8, 2025 21:06
@alii alii changed the title Runtime React framework implementation(s) [WIP] Runtime React framework implementation(s) Sep 8, 2025
@alii
alii marked this pull request as ready for review October 3, 2025 18:14
@coderabbitai

coderabbitai Bot commented Oct 3, 2025 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

💤 Files selected but had no reviewable changes (5)
  • src/cli.zig
  • src/cli/Arguments.zig
  • src/node-fallbacks/package.json
  • test/bake/bake-harness.ts
  • test/bake/fixtures/react-spa-simple/package.json
⛔ Files ignored due to path filters (2)
  • src/node-fallbacks/bun.lock is excluded by !**/*.lock
  • test/bun.lock is excluded by !**/*.lock

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

Adds a new standalone package packages/bun-framework-react (RSC runtime, router, client/server/SSR entries, vendored react-server-dom-bun and typings), broad bun:app TypeScript declarations, dynamic framework resolution in Bake, removal of the legacy in-repo React framework, and assorted tooling/config updates.

Changes

Cohort / File(s) Summary of changes
New Bun Framework React package
packages/bun-framework-react/package.json, packages/bun-framework-react/README.md, packages/bun-framework-react/tsconfig.json, packages/bun-framework-react/.gitignore, packages/bun-framework-react/*, packages/bun-framework-react/src/*, packages/bun-framework-react/src/components/*
Adds a new package implementing the Bun Rendering API with RSC: framework config export, client/server/SSR entry points, router, CSS manager, app state/store, utilities, Link component, and public exports.
Vendored react-server-dom-bun and typings
packages/bun-framework-react/vendor/**, packages/bun-framework-react/vendor/react-server-dom-bun/package.json, packages/bun-framework-react/vendor/react-server-dom-bun/*.d.ts, packages/bun-framework-react/vendor/react-server-dom-bun/cjs/*
Adds vendored react-server-dom-bun distribution (multiple CJS/UMD/ESM variants), README, LICENSE, shims that select prod/dev bundles, and corresponding type declarations and package metadata.
Bake core & module loader changes
src/bake.zig, src/bake/BakeGlobalObject.cpp, src/bake/DevServer.zig
Adds extern to extract default exports, makes UserOptions.fromJS accept a resolver and resolve external frameworks via resolver, removes built-in React embedding, updates virtual bun:app/* source paths, and tightens module loader error handling and DevServer note behavior.
Public types: bun:app + package typings
packages/bun-types/app.d.ts, packages/bun-types/index.d.ts, src/bake/bake.d.ts, src/bake/bake.private.d.ts
Introduces comprehensive bun:app declaration surface and updates private Bake typings; removes legacy src/bake/bake.d.ts Bake public defs and adjusts several internal type signatures.
Client runtime refactor / removals
src/bake/bun-framework-react/client.tsx (deleted), src/bake/bun-framework-react/index.ts (deleted)
Removes prior in-repo Bun framework React client and framework entry used by Bake.
New client runtime implementation
packages/bun-framework-react/client.tsx, packages/bun-framework-react/server.tsx, packages/bun-framework-react/ssr.tsx, packages/bun-framework-react/src/client/*
Adds client hydration, initial RSC payload streaming, AppState/store, Root component, Router with prefetch/navigate/caching, BakeCSSManager, isThenable util, and SSR/streaming updates.
Small libraries & components
packages/bun-framework-react/src/client/store.ts, packages/bun-framework-react/src/components/link.tsx, packages/bun-framework-react/src/client/lib/util.ts, packages/bun-framework-react/src/client/constants.ts
Adds a minimal store API, Link component wiring hover-prefetch/click navigation to router, isThenable predicate, and exports a singleton router.
Build / tooling / config updates
.gitattributes, cmake/Sources.json, .vscode/launch.json, package.json, packages/bun-vscode/example/package.json
Marks vendor path as linguist-vendored, adds CMake source grouping for BunFrameworkReact, updates VSCode debug args/cwd, pins @types/node resolution, and adjusts example package deps.
Bake client tooling tweaks
src/bake/client/{data-view.ts,overlay.ts,stack-trace.ts,websocket.ts}
Typing refinements and DOM/logging/overlay helper improvements.
Zig AST and visit changes
src/ast/visitExpr.zig
Removes prior server-component hook enforcement (useState check) from visitExpr, simplifying hook-detection logic.

Possibly related PRs

Suggested reviewers

  • Jarred-Sumner
  • zackradisic
  • pfgithub

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The description uses the required template headings but only contains placeholder “wip” text and does not explain what the PR does or how it was verified, leaving critical information missing for reviewers. Please replace the “wip” placeholders with a detailed summary of the PR’s purpose and the steps taken to verify functionality, including testing strategies or example commands to reproduce the changes.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title summarizes the main change by indicating an implementation of the React Rendering API framework, but the “[WIP]” prefix is unnecessary and should be removed before merging to keep the history clean and focused.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

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

@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: 25

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (7)
src/bake.zig (1)

562-575: Critical: ignoreDirs parsing uses wrong iterator and wrong length; fix off-by-many and OOB risks

  • Uses array.arrayIterator instead of exts_js.arrayIterator.
  • Allocates dirs with len (routerTypes length) instead of the number of ignoreDirs entries.
  • Error message mentions “extensions”.

This can cause incorrect sizes and out-of-bounds writes.

-                const ignore_dirs: []const []const u8 = if (try fsr_opts.get(global, "ignoreDirs")) |exts_js| exts: {
-                    if (exts_js.isArray()) {
-                        var it_2 = try array.arrayIterator(global);
-                        var i_2: usize = 0;
-                        const dirs = try arena.alloc([]const u8, len);
-                        while (try it_2.next()) |array_item| : (i_2 += 1) {
-                            dirs[i_2] = refs.track(try array_item.toSlice(global, arena));
-                        }
-                        break :exts dirs;
-                    }
-
-                    return global.throwInvalidArguments("'ignoreDirs' must be an array of strings or \"*\" for all extensions", .{});
-                } else &.{ ".git", "node_modules" };
+                const ignore_dirs: []const []const u8 = if (try fsr_opts.get(global, "ignoreDirs")) |exts_js| exts: {
+                    if (exts_js.isArray()) {
+                        var it_2 = try exts_js.arrayIterator(global);
+                        var i_2: usize = 0;
+                        const count = try exts_js.getLength(global);
+                        const dirs = try arena.alloc([]const u8, count);
+                        while (try it_2.next()) |array_item| : (i_2 += 1) {
+                            dirs[i_2] = refs.track(try array_item.toSlice(global, arena));
+                        }
+                        break :exts dirs;
+                    }
+
+                    return global.throwInvalidArguments("'ignoreDirs' must be an array of strings", .{});
+                } else &.{ ".git", "node_modules" };
packages/bun-framework-react/server.tsx (5)

94-99: CSS metadata length is wrong (use bytes, not string length).

str.length counts code units, not bytes. This truncates non‑ASCII and breaks CSS preloading.

Apply:

-    const int = Buffer.allocUnsafe(4);
-    const str = meta.styles.join("\n");
-    int.writeUInt32LE(str.length, 0);
-    rscPayload.write(int);
-    rscPayload.write(str);
+    const cssMeta = Buffer.from(meta.styles.join("\n"), "utf8");
+    const int = Buffer.allocUnsafe(4);
+    int.writeUInt32LE(cssMeta.byteLength, 0);
+    rscPayload.write(int);
+    rscPayload.write(cssMeta);

172-176: Prerender header/value mismatch (writes count, not byte length).

You’re writing the number of styles, then a string; reader expects a byte length header and raw bytes.

Apply:

-  const int = new Uint32Array(1);
-  int[0] = meta.styles.length;
-  let rscChunks: Array<BlobPart> = [int.buffer as ArrayBuffer, meta.styles.join("\n")];
+  const enc = new TextEncoder();
+  const cssMeta = enc.encode(meta.styles.join("\n"));
+  const int = new Uint32Array(1);
+  int[0] = cssMeta.byteLength;
+  let rscChunks: Array<BlobPart> = [int.buffer, cssMeta];

117-124: Avoid overriding framework-set headers; normalize header merging.

Spreading responseOptions after a headers literal can silently override Content‑Type. Normalize merge with Headers.

Apply:

-    const responseOptions = als?.getStore()?.responseOptions || {};
-    return new Response(rscPayload as any, {
-      status: 200,
-      headers: { "Content-Type": "text/x-component" },
-      ...responseOptions,
-    });
+    const opts = als?.getStore()?.responseOptions ?? { headers: {} };
+    const { headers: extraHeaders, ...response_options } = opts;
+    const finalHeaders = new Headers(extraHeaders);
+    finalHeaders.set("Content-Type", "text/x-component");
+    return new Response(rscPayload as any, {
+      status: 200,
+      headers: finalHeaders,
+      ...response_options,
+    });

128-139: Same header merge issue in streaming branch.

Ensure Content‑Type isn’t lost when responseOptions includes headers.

Apply:

-    const responseOptions = als?.getStore()?.responseOptions || {};
-    if (als) {
+    const opts = als?.getStore()?.responseOptions ?? { headers: {} };
+    if (als) {
       const state = als.getStore();
       if (state) state.streamingStarted = true;
     }
-    // Stream the response as before
-    return new Response(renderToHtml(rscPayload, meta.modules, signal), {
-      headers: {
-        "Content-Type": "text/html; charset=utf8",
-      },
-      ...responseOptions,
-    });
+    const { headers: extraHeaders, ...response_options } = opts;
+    const finalHeaders = new Headers(extraHeaders);
+    finalHeaders.set("Content-Type", "text/html; charset=utf8");
+    return new Response(renderToHtml(rscPayload, meta.modules, signal), {
+      headers: finalHeaders,
+      ...response_options,
+    });

145-158: Use Headers API to append multiple Set-Cookie headers

A plain object can’t carry multiple “Set-Cookie” values. Construct a Headers instance, set Content-Type, then append each cookie from request.cookies.toSetCookieHeaders():

-  const opts = als?.getStore()?.responseOptions ?? { headers: {} };
-  const { headers, ...response_options } = opts;
-
-  const cookies = meta.pageModule.mode === "ssr" ? { "Set-Cookie": request.cookies.toSetCookieHeaders() } : {};
-
-  return new Response(result, {
-    headers: {
-      "Content-Type": "text/html; charset=utf8",
-      // TODO: merge cookies and cookies inside of headers
-      ...cookies,
-      ...headers,
-    },
-    ...response_options,
-  });
+  const opts = als?.getStore()?.responseOptions ?? { headers: {} };
+  const { headers: extraHeaders, ...response_options } = opts;
+  const finalHeaders = new Headers(extraHeaders);
+  finalHeaders.set("Content-Type", "text/html; charset=utf8");
+  const cookieHeaders = meta.pageModule.mode === "ssr"
+    ? request.cookies.toSetCookieHeaders()
+    : [];
+  for (const c of cookieHeaders) finalHeaders.append("Set-Cookie", c);
+  return new Response(result, {
+    headers: finalHeaders,
+    ...response_options,
+  });
packages/bun-framework-react/ssr.tsx (1)

75-85: Potential hang: stream.finished never resolves on error.

onError closes the controller and aborts React, but doesn’t reject the RscInjectionStream’s finished promise. pull() returns stream.finished, so callers can hang.

Apply:

       onError(error) {
         if (!signal.aborted) {
           // Abort the rendering and close the stream
           signal.aborted = error as Error;
           abort();
           if (signal.abort) signal.abort();
           if (stream) {
-            stream.controller.close();
+            // Reject finished so pull() completes with error, then close
+            stream.reject(error);
+            stream.controller.close();
           }
         }
       },
♻️ Duplicate comments (1)
packages/bun-framework-react/vendor/react-server-dom-bun/static.node.unbundled.js (1)

4-8: Same NODE_ENV fallback consideration applies.

Like static.node.js, this file treats any non-'production' value as development. The same optional validation suggestion applies here.

🧹 Nitpick comments (30)
src/bake/client/stack-trace.ts (1)

55-82: Consider reverting to inline object return for consistency and conciseness.

The explicit return type annotation on line 55 and the two-step variable-then-return pattern (lines 74-81) add verbosity without clear benefit:

  1. TypeScript can infer the Frame return type from the object shape and interface
  2. The intermediate variable doesn't improve readability for this simple transformation
  3. This creates inconsistency with parseFFOrSafari (lines 85-116), which uses inline object returns

The original pattern (inline object with satisfies Frame if type assertion was needed) is more idiomatic for .map() callbacks in modern TypeScript.

Consider this more concise approach:

-    .map((line): Frame => {
+    .map((line) => {
       let sanitizedLine = line
         .replace(/^\s+/, "")
         .replace(/\(eval code/g, "(")
         .replace(/^.*?\s+/, "");
 
       // capture and preserve the parenthesized location "(/foo/my bar.js:12:87)" in
       // case it has spaces in it, as the string is split on \s+ later on
       let loc = sanitizedLine.match(/ (\(.+\)$)/);
 
       // remove the parenthesized location from the line, if it was matched
       sanitizedLine = loc ? sanitizedLine.replace(loc[0], "") : sanitizedLine;
 
       // if a location was matched, pass it to extractLocation() otherwise pass all sanitizedLine
       // because this line doesn't have function name
       let locationParts = extractLocation(loc ? loc[1] : sanitizedLine);
       let functionName = (loc && sanitizedLine) || undefined;
       let fileName = ["eval", "<anonymous>"].indexOf(locationParts[0]) > -1 ? undefined : locationParts[0];
 
-      const frame: Frame = {
+      return {
         fn: functionName || "unknown",
         file: fileName,
         line: 0 | locationParts[1],
         col: 0 | locationParts[2],
       };
-
-      return frame;
     });
.vscode/launch.json (1)

60-64: Rename to match behavior and verify cwd for app builds

This config is named “bun run [file]” but now runs “build --app” with cwd = ${fileDirname}. That’s confusing and may break workflows that expect to run the current file. Recommend:

  • Rename to “bun build --app” (or add a new config for build and keep the old “run [file]”).
  • Verify whether the app expects to resolve from workspace root; if so, set cwd = ${workspaceFolder}.
  • Consider aligning the Windows config with this behavior for parity.

Example minimal fix:

-      "name": "bun run [file]",
+      "name": "bun build --app",
-      "args": ["build", "--app"],
+      "args": ["build", "--app"],
-      "cwd": "${fileDirname}",
+      "cwd": "${workspaceFolder}",

Based on learnings

src/bake/client/overlay.ts (2)

82-98: Consider using Object.keys() or hasOwnProperty with for...in.

The for...in loop iterates over all enumerable properties, including inherited ones. While this is likely safe given the expected plain object usage, using Object.keys(props) would be more explicit and avoid potential issues if props ever has a prototype chain.

Optional refactor:

   if (props) {
-    for (const key in props) {
+    for (const key of Object.keys(props)) {
       const value = props[key];
       if (value === undefined) continue;
       node.setAttribute(key, value);
     }
   }

100-111: Consider using Object.keys() for consistency with elem.

The same for...in consideration applies here. Using Object.keys(props) would avoid iterating over inherited properties.

Optional refactor:

   if (props) {
-    for (const key in props) {
+    for (const key of Object.keys(props)) {
       const value = props[key];
       if (value === undefined) continue;
       node.setAttribute(key, value);
     }
   }
src/ast/visitExpr.zig (1)

36-48: Clarify the intent of the commented-out hook list.

The commented-out list of well-known client-only React hooks (useState, useEffect, etc.) suggests incomplete implementation or future use. Since this is dead code with no functional impact, consider:

  • If this list is intended for future use, add a TODO comment explaining when/how it will be used.
  • If this list is no longer needed, remove it to avoid clutter.

Given that this PR is marked [WIP] and the build is failing, could you clarify whether this commented-out code should remain? If it's intended for future use, adding a brief TODO comment would improve clarity.

src/bake/BakeGlobalObject.cpp (1)

143-145: Consider validating URL before constructing SourceOrigin.

The code asserts that the URL is valid (line 144), but this only runs in debug builds. If moduleKey is malformed (e.g., contains invalid characters or spaces after bake:/), WTF::URL might be invalid in release builds, potentially causing issues in source mapping or debugging.

Consider validating the URL and handling the error case:

                 WTF::URL url = WTF::URL(moduleKey);
-                ASSERT(url.isValid());
+                if (!url.isValid()) [[unlikely]] {
+                    return rejectedInternalPromise(globalObject, 
+                        createTypeError(globalObject, makeString("Invalid bake:/ URL: "_s, moduleKey)));
+                }
                 JSC::SourceOrigin origin = JSC::SourceOrigin(WTFMove(url));
packages/bun-framework-react/tsconfig.json (2)

3-3: Add DOM.Iterable to lib

Improves typings for iterable DOM collections (e.g., URLSearchParams.entries(), NodeListOf iteration).

-    "lib": ["ESNext", "DOM"],
+    "lib": ["ESNext", "DOM", "DOM.Iterable"],

2-23: Include Bun types in tsconfig
In packages/bun-framework-react/tsconfig.json, add under compilerOptions:

   "compilerOptions": {
+    "types": ["bun-types"],

This ensures Bun’s global APIs are recognized.

packages/bun-framework-react/vendor/react-server-dom-bun/static.node.js (1)

4-8: Consider explicit NODE_ENV fallback or validation.

The current logic treats any non-'production' value as development. While this is a common pattern, it silently loads the development bundle for typos like 'productoin' or unexpected values like 'staging'.

For clarity, consider explicitly checking for known values:

 var s;
-if (process.env.NODE_ENV === 'production') {
+if (process.env.NODE_ENV === 'production') {
   s = require('./cjs/react-server-dom-bun-server.node.production.js');
+} else if (process.env.NODE_ENV === 'development' || !process.env.NODE_ENV) {
+  s = require('./cjs/react-server-dom-bun-server.node.development.js');
 } else {
-  s = require('./cjs/react-server-dom-bun-server.node.development.js');
+  throw new Error(`Unexpected NODE_ENV: ${process.env.NODE_ENV}`);
 }

Alternatively, keep the current behavior if the fallback-to-dev pattern is intentional for this vendored package.

packages/bun-framework-react/vendor/react-server-dom-bun/static.node.unbundled.js (1)

1-12: Consider extracting the environment-detection pattern.

Both static.node.js and static.node.unbundled.js duplicate the NODE_ENV detection logic (lines 1-8). While the duplication is minimal, extracting a shared helper could improve maintainability.

Example helper module (env-loader.js):

'use strict';

exports.loadEnvSpecific = function(prodPath, devPath) {
  if (process.env.NODE_ENV === 'production') {
    return require(prodPath);
  } else {
    return require(devPath);
  }
};

Then simplify both files:

'use strict';

var loadEnvSpecific = require('./env-loader').loadEnvSpecific;
var s = loadEnvSpecific(
  './cjs/react-server-dom-bun-server.node.unbundled.production.js',
  './cjs/react-server-dom-bun-server.node.unbundled.development.js'
);

if (s.unstable_prerenderToNodeStream) {
  exports.unstable_prerenderToNodeStream = s.unstable_prerenderToNodeStream;
}

This is a minor refactor and can be deferred if preferred for this vendored code.

packages/bun-framework-react/vendor/react-server-dom-bun/server.js (1)

3-6: Consider adjusting error message for Bun context.

The error message references Node.js specifically (--conditions react-server flag), but this file is part of bun-framework-react. Bun users may find the Node.js-specific instruction confusing. Consider whether the message should mention Bun's equivalent mechanism or provide Bun-specific guidance.

packages/bun-framework-react/vendor/react-server-dom-bun/static.js (1)

1-6: Clarify purpose of duplicate environment guard and adjust messaging.

This file is identical to server.js. If both serve as entry points for different module resolution conditions, consider:

  1. Deduplication: Extract the guard logic to a shared module that both can require.
  2. Bun-specific messaging: The error references Node.js --conditions react-server, but this is in a Bun package. Adjust the message to provide Bun-specific guidance or clarify cross-runtime usage.

Verify the distinct purposes of server.js and static.js:

#!/bin/bash
# Description: Check if server.js and static.js are referenced differently

# Look for references to these specific entry points
rg -n "static\.js|server\.js" packages/bun-framework-react/vendor/react-server-dom-bun/package.json
rg -n "(require|import).*['\"].*/(static|server)\.js" packages/bun-framework-react/
packages/bun-framework-react/vendor/react-server-dom-bun/client.js (1)

3-3: Forwarding to browser build may mis-route in Node if consumers bypass "exports".

If a consumer deep-imports "…/client.js" ignoring the exports map, they'll always get the browser build. Either remove this file (prefer relying on package.json exports), or make it conditional to avoid surprises.

Example conditional shim:

-'use strict';
-
-module.exports = require('./client.browser');
+'use strict';
+
+// Prefer package.json "exports" map. This is a safety guard for tools that bypass it.
+const isNode = typeof process !== 'undefined' && !!(process.versions && process.versions.node);
+module.exports = isNode ? require('./client.node') : require('./client.browser');
packages/bun-framework-react/src/client/store.ts (1)

22-33: Avoid relying on this binding in write; and return void unsubscribe.

Safer to use the closed-over value instead of this.read(). Also adapt unsubscribe to return void.

-    write(next) {
-      const current = this.read();
+    write(next) {
+      const current = value;
       const resolved = next instanceof Function ? next(current) : next;
       if (Object.is(current, resolved)) return;
       value = resolved;
       notify(subscribers);
     },
@@
-    subscribe(callback) {
+    subscribe(callback) {
       subscribers.add(callback);
-      return () => subscribers.delete(callback);
+      return () => {
+        subscribers.delete(callback);
+      };
     },
packages/bun-framework-react/vendor/react-server-dom-bun/package.json (1)

81-83: Node engines field seems too permissive.

RSC stacks generally require modern runtimes (≥18). Consider tightening engines to reflect reality and avoid unsupported installs.

packages/bun-framework-react/vendor/react-server-dom-bun/cjs/react-server-dom-bun-client.browser.production.js (1)

659-660: Treat vendor bundle as lint/format ignore; do not “fix” upstream semantics.

Biome flags (thenable prototype, switch fallthrough, declarations in cases, shadowing “constructor”) are expected in React’s compiled runtime. Please exclude packages/bun-framework-react/vendor/** from Biome and Prettier instead of modifying vendored code.

Suggested config updates:

  • .biome.json (or biome.json):
{
  "files": {
    "ignore": ["packages/bun-framework-react/vendor/**"]
  }
}
  • .prettierignore:
packages/bun-framework-react/vendor/

Also applies to: 746-759, 920-925, 1661-1661

packages/bun-framework-react/vendor/react-server-dom-bun/cjs/react-server-dom-bun-client.node.production.js (1)

659-660: Exclude vendor from Biome/Prettier; compiled patterns are intentional.

Flags for prototype then, fallthrough, case-scoped declarations, and restricted-name shadowing are intentional in upstream React builds. Ignore packages/bun-framework-react/vendor/** in lint/format to prevent noisy failures.

Also applies to: 746-759, 920-925, 1661-1661, 1785-1785

packages/bun-framework-react/vendor/react-server-dom-bun/cjs/react-server-dom-bun-server.node.unbundled.production.js (1)

467-467: Silence lints for vendored server runtime; do not modify upstream.

Multiple Biome warnings (switch declarations, restricted-name shadowing, prototype then, use-before-declaration) stem from React’s compiled server runtime. Exclude packages/bun-framework-react/vendor/** from Biome/Prettier rather than patching this file.

Also applies to: 532-532, 919-919, 1147-1148, 1821-1822, 2085-2085, 2118-2118, 2342-2343, 402-405

packages/bun-framework-react/src/client/root.tsx (1)

16-26: Add effect deps and cancel the scheduled animation frame

Running this layout effect on every render without cleanup can queue redundant RAFs. Scope it to relevant changes and cancel on re-render/unmount.

-  useLayoutEffect(() => {
+  useLayoutEffect(() => {
     if (app.abortOnRender) {
       try {
         app.abortOnRender.abort();
       } catch {}
     }
 
-    requestAnimationFrame(() => {
-      router.css.disableUnusedCssFilesIfNeeded();
-    });
-  });
+    const id = requestAnimationFrame(() => {
+      router.css.disableUnusedCssFilesIfNeeded();
+    });
+    return () => cancelAnimationFrame(id);
+  }, [app.abortOnRender]);
packages/bun-framework-react/client.tsx (1)

39-48: Harden view-transition stylesheet injection

Guard for adoptedStyleSheets/CSSStyleSheet support to avoid runtime errors on partially supported browsers.

-  if (document.startViewTransition !== undefined) {
+  if (
+    document.startViewTransition !== undefined &&
+    "adoptedStyleSheets" in document &&
+    typeof CSSStyleSheet !== "undefined"
+  ) {
     const sheet = new CSSStyleSheet();
     document.adoptedStyleSheets.push(sheet);
     sheet.replaceSync(":where(*)::view-transition-group(root){animation:none}");
   }
packages/bun-framework-react/vendor/react-server-dom-bun/client.node.unbundled.d.ts (2)

9-12: Narrow crossOrigin type for correctness

Limit to valid values to catch mistakes at compile time.

 export interface ModuleLoading {
   prefix: string;
-  crossOrigin?: string;
+  crossOrigin?: "anonymous" | "use-credentials";
 }

14-18: Avoid loose any in public types

If possible, prefer unknown or specific function types to improve type safety.

 export interface Options {
-  encodeFormAction?: any;
-  findSourceMapURL?: any;
+  encodeFormAction?: (x: unknown) => unknown;
+  findSourceMapURL?: (source: string) => string | null | undefined;
   environmentName?: string;
 }
packages/bun-framework-react/vendor/react-server-dom-bun/server.node.unbundled.d.ts (2)

4-8: Avoid generic shadowing inside PipeableStream

Rename the method generic to prevent shadowing the interface’s T.

 export interface PipeableStream<T> {
   /** Returns the input, which should match the Node.js writable interface */
-  pipe: <T extends NodeJS.WritableStream>(destination: T) => T;
+  pipe: <W extends NodeJS.WritableStream>(destination: W) => W;
   abort: () => void;
 }

10-14: Consider removing unused generic parameter T

If T is not used elsewhere in PipeableStream, the generic on renderToPipeableStream adds noise.

-export function renderToPipeableStream<T = any>(
+export function renderToPipeableStream(
   model: ReactElement,
   webpackMap: ServerManifest,
   options?: RenderToPipeableStreamOptions,
-): PipeableStream<T>;
+): PipeableStream<any>;
packages/bun-framework-react/vendor/react-server-dom-bun/cjs/react-server-dom-bun-client.node.unbundled.production.js (1)

1-2125: Do not lint vendor bundle; exclude from Biome/ESLint.

Static-analysis flags (fallthrough, noSwitchDeclarations, noThenProperty, shadowing) stem from compiled React code. Exclude packages/bun-framework-react/vendor/** from linters to avoid noise.

Add ignore config (e.g., .biome.json, .eslintignore) to skip vendor/.

packages/bun-framework-react/ssr.tsx (3)

51-61: Duplicate abort check (remove one and avoid passing reason to close).

Two identical early-abort blocks exist. Keep a single check and call controller.close() without an argument to avoid relying on nonstandard signature.

Apply:

-      // If the signal is already aborted, we should not proceed
-      if (signal.aborted) {
-        controller.close(signal.aborted);
-        return Promise.reject(signal.aborted);
-      }
-
-      // If the signal is already aborted, we should not proceed
-      if (signal.aborted) {
-        controller.close(signal.aborted);
-        return Promise.reject(signal.aborted);
-      }
+      // If the signal is already aborted, we should not proceed
+      if (signal.aborted) {
+        controller.close();
+        return Promise.reject(signal.aborted);
+      }

If Bun’s Direct controller supports a reason, reply and I can adjust accordingly.


318-321: Use fatal UTF‑8 decoding in static path for consistency.

StaticRscInjectionStream uses TextDecoder without fatal; dynamic path uses fatal and falls back to base64 on invalid UTF‑8. Make static consistent.

Apply:

-    writeManyFlightScriptData(this.rscPayloadChunks, new TextDecoder("utf-8"), { write: str => (string += str) });
+    writeManyFlightScriptData(
+      this.rscPayloadChunks,
+      new TextDecoder("utf-8", { fatal: true }),
+      { write: str => (string += str) }
+    );

185-188: shellReady flag is written but never used.

onShellReady()/shellReady don’t affect injection logic. Either wire it into write/drain decisions or remove.

Would you like me to gate RSC injection until shellReady to reduce early interleaving?

packages/bun-framework-react/vendor/react-server-dom-bun/cjs/react-server-dom-bun-server.browser.production.js (1)

11-20: Vendor file: exclude from lint/format and verify Buffer polyfill in browser contexts.

Static analysis flags (switch declarations, shadowing, .then on objects) stem from upstream minified code. Don’t refactor vendor sources; instead, disable linters for this file and ensure your build treats it as vendored.

  • Add a header disable comment for your linters (Biome/ESLint/Prettier), e.g.:
    /* biome-ignore file */
  • Confirm Buffer.byteLength is available wherever this module executes. If it can run in “browser” graphs, ensure Bun’s Buffer polyfill is injected.

I can add a repo-safe script to check which graphs include this file and whether Buffer polyfills are emitted where needed.

packages/bun-types/app.d.ts (1)

662-680: Make importSource optional (aligns with docs and usage).

Avoid requiring the property with undefined; mark it optional.

Apply:

-  interface ReactFastRefreshOptions {
+  interface ReactFastRefreshOptions {
     /**
      * ...
      */
-    importSource: string | undefined;
+    importSource?: string;
   }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between c8cb771 and d7217f26d52f44f9d10dc7b57d4aebdc26afa2b1.

⛔ Files ignored due to path filters (4)
  • bun.lock is excluded by !**/*.lock
  • packages/bun-framework-react/bun.lock is excluded by !**/*.lock
  • test/bake/fixtures/react-spa-simple/bun.lock is excluded by !**/*.lock
  • test/bun.lock is excluded by !**/*.lock
📒 Files selected for processing (63)
  • .gitattributes (1 hunks)
  • .vscode/launch.json (1 hunks)
  • cmake/Sources.json (1 hunks)
  • package.json (1 hunks)
  • packages/bun-framework-react/.gitignore (1 hunks)
  • packages/bun-framework-react/README.md (1 hunks)
  • packages/bun-framework-react/client.tsx (1 hunks)
  • packages/bun-framework-react/index.ts (1 hunks)
  • packages/bun-framework-react/package.json (1 hunks)
  • packages/bun-framework-react/server.tsx (4 hunks)
  • packages/bun-framework-react/src/client/app.ts (1 hunks)
  • packages/bun-framework-react/src/client/constants.ts (1 hunks)
  • packages/bun-framework-react/src/client/css.ts (1 hunks)
  • packages/bun-framework-react/src/client/lib/util.ts (1 hunks)
  • packages/bun-framework-react/src/client/root.tsx (1 hunks)
  • packages/bun-framework-react/src/client/router.ts (1 hunks)
  • packages/bun-framework-react/src/client/store.ts (1 hunks)
  • packages/bun-framework-react/src/components/link.tsx (1 hunks)
  • packages/bun-framework-react/ssr.tsx (14 hunks)
  • packages/bun-framework-react/tsconfig.json (1 hunks)
  • packages/bun-framework-react/vendor/.prettierignore (1 hunks)
  • packages/bun-framework-react/vendor/react-server-dom-bun/LICENSE (1 hunks)
  • packages/bun-framework-react/vendor/react-server-dom-bun/README.md (1 hunks)
  • packages/bun-framework-react/vendor/react-server-dom-bun/cjs/react-server-dom-bun-client.browser.production.js (1 hunks)
  • packages/bun-framework-react/vendor/react-server-dom-bun/cjs/react-server-dom-bun-client.node.production.js (1 hunks)
  • packages/bun-framework-react/vendor/react-server-dom-bun/cjs/react-server-dom-bun-client.node.unbundled.production.js (1 hunks)
  • packages/bun-framework-react/vendor/react-server-dom-bun/cjs/react-server-dom-bun-server.browser.production.js (1 hunks)
  • packages/bun-framework-react/vendor/react-server-dom-bun/cjs/react-server-dom-bun-server.node.production.js (1 hunks)
  • packages/bun-framework-react/vendor/react-server-dom-bun/cjs/react-server-dom-bun-server.node.unbundled.production.js (1 hunks)
  • packages/bun-framework-react/vendor/react-server-dom-bun/client.browser.d.ts (1 hunks)
  • packages/bun-framework-react/vendor/react-server-dom-bun/client.browser.js (1 hunks)
  • packages/bun-framework-react/vendor/react-server-dom-bun/client.js (1 hunks)
  • packages/bun-framework-react/vendor/react-server-dom-bun/client.node.js (1 hunks)
  • packages/bun-framework-react/vendor/react-server-dom-bun/client.node.unbundled.d.ts (1 hunks)
  • packages/bun-framework-react/vendor/react-server-dom-bun/client.node.unbundled.js (1 hunks)
  • packages/bun-framework-react/vendor/react-server-dom-bun/esm/package.json (1 hunks)
  • packages/bun-framework-react/vendor/react-server-dom-bun/index.js (1 hunks)
  • packages/bun-framework-react/vendor/react-server-dom-bun/package.json (1 hunks)
  • packages/bun-framework-react/vendor/react-server-dom-bun/plugin.js (1 hunks)
  • packages/bun-framework-react/vendor/react-server-dom-bun/server.browser.js (1 hunks)
  • packages/bun-framework-react/vendor/react-server-dom-bun/server.js (1 hunks)
  • packages/bun-framework-react/vendor/react-server-dom-bun/server.node.js (1 hunks)
  • packages/bun-framework-react/vendor/react-server-dom-bun/server.node.unbundled.d.ts (1 hunks)
  • packages/bun-framework-react/vendor/react-server-dom-bun/server.node.unbundled.js (1 hunks)
  • packages/bun-framework-react/vendor/react-server-dom-bun/static.browser.js (1 hunks)
  • packages/bun-framework-react/vendor/react-server-dom-bun/static.js (1 hunks)
  • packages/bun-framework-react/vendor/react-server-dom-bun/static.node.js (1 hunks)
  • packages/bun-framework-react/vendor/react-server-dom-bun/static.node.unbundled.js (1 hunks)
  • packages/bun-types/app.d.ts (1 hunks)
  • packages/bun-types/index.d.ts (1 hunks)
  • packages/bun-vscode/example/package.json (1 hunks)
  • src/ast/visitExpr.zig (2 hunks)
  • src/bake.zig (8 hunks)
  • src/bake/BakeGlobalObject.cpp (2 hunks)
  • src/bake/DevServer.zig (0 hunks)
  • src/bake/bake.d.ts (0 hunks)
  • src/bake/bake.private.d.ts (3 hunks)
  • src/bake/bun-framework-react/client.tsx (0 hunks)
  • src/bake/bun-framework-react/index.ts (0 hunks)
  • src/bake/client/data-view.ts (1 hunks)
  • src/bake/client/overlay.ts (6 hunks)
  • src/bake/client/stack-trace.ts (2 hunks)
  • src/bake/client/websocket.ts (1 hunks)
💤 Files with no reviewable changes (4)
  • src/bake/bun-framework-react/index.ts
  • src/bake/DevServer.zig
  • src/bake/bake.d.ts
  • src/bake/bun-framework-react/client.tsx
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Format JavaScript/TypeScript files with Prettier (bun run prettier)

Files:

  • packages/bun-framework-react/src/client/constants.ts
  • packages/bun-framework-react/src/client/root.tsx
  • packages/bun-framework-react/vendor/react-server-dom-bun/client.browser.d.ts
  • packages/bun-framework-react/vendor/react-server-dom-bun/client.node.unbundled.js
  • packages/bun-framework-react/vendor/react-server-dom-bun/static.node.unbundled.js
  • packages/bun-types/index.d.ts
  • packages/bun-framework-react/src/client/css.ts
  • packages/bun-framework-react/server.tsx
  • packages/bun-framework-react/client.tsx
  • src/bake/client/websocket.ts
  • packages/bun-framework-react/src/client/router.ts
  • src/bake/client/data-view.ts
  • packages/bun-framework-react/vendor/react-server-dom-bun/cjs/react-server-dom-bun-client.node.unbundled.production.js
  • packages/bun-framework-react/vendor/react-server-dom-bun/server.js
  • packages/bun-framework-react/src/components/link.tsx
  • src/bake/client/overlay.ts
  • packages/bun-framework-react/vendor/react-server-dom-bun/cjs/react-server-dom-bun-client.browser.production.js
  • packages/bun-framework-react/vendor/react-server-dom-bun/static.node.js
  • packages/bun-framework-react/vendor/react-server-dom-bun/index.js
  • src/bake/client/stack-trace.ts
  • packages/bun-framework-react/src/client/app.ts
  • packages/bun-framework-react/vendor/react-server-dom-bun/server.node.js
  • packages/bun-framework-react/vendor/react-server-dom-bun/client.browser.js
  • packages/bun-framework-react/src/client/lib/util.ts
  • packages/bun-framework-react/vendor/react-server-dom-bun/client.node.js
  • packages/bun-framework-react/index.ts
  • packages/bun-framework-react/vendor/react-server-dom-bun/plugin.js
  • packages/bun-framework-react/vendor/react-server-dom-bun/cjs/react-server-dom-bun-client.node.production.js
  • packages/bun-framework-react/vendor/react-server-dom-bun/server.node.unbundled.d.ts
  • packages/bun-framework-react/ssr.tsx
  • packages/bun-framework-react/vendor/react-server-dom-bun/server.node.unbundled.js
  • packages/bun-framework-react/src/client/store.ts
  • packages/bun-framework-react/vendor/react-server-dom-bun/cjs/react-server-dom-bun-server.node.unbundled.production.js
  • packages/bun-framework-react/vendor/react-server-dom-bun/server.browser.js
  • packages/bun-framework-react/vendor/react-server-dom-bun/static.js
  • packages/bun-framework-react/vendor/react-server-dom-bun/cjs/react-server-dom-bun-server.node.production.js
  • packages/bun-framework-react/vendor/react-server-dom-bun/client.node.unbundled.d.ts
  • packages/bun-framework-react/vendor/react-server-dom-bun/client.js
  • packages/bun-framework-react/vendor/react-server-dom-bun/static.browser.js
  • src/bake/bake.private.d.ts
  • packages/bun-types/app.d.ts
  • packages/bun-framework-react/vendor/react-server-dom-bun/cjs/react-server-dom-bun-server.browser.production.js
src/**/*.zig

📄 CodeRabbit inference engine (.cursor/rules/building-bun.mdc)

Implement debug logs in Zig using const log = bun.Output.scoped(.${SCOPE}, false); and invoking log("...", .{})

Files:

  • src/ast/visitExpr.zig
  • src/bake.zig
**/*.zig

📄 CodeRabbit inference engine (.cursor/rules/javascriptcore-class.mdc)

**/*.zig: Declare the extern C symbol in Zig and export a Zig-friendly alias for use
Wrap the Bun____toJS extern in a Zig method that takes a JSGlobalObject and returns JSC.JSValue

**/*.zig: Format Zig files with zig-format (bun run zig-format)
In Zig, manage memory carefully with allocators and use defer for cleanup

Files:

  • src/ast/visitExpr.zig
  • src/bake.zig
**/*.{cpp,h}

📄 CodeRabbit inference engine (.cursor/rules/javascriptcore-class.mdc)

**/*.{cpp,h}: When exposing a JS class with public Constructor and Prototype, define three C++ types: class Foo : public JSC::DestructibleObject (if it has C++ fields), class FooPrototype : public JSC::JSNonFinalObject, and class FooConstructor : public JSC::InternalFunction
If the class has C++ data members, inherit from JSC::DestructibleObject and provide proper destruction; if it has no C++ fields (only JS properties), avoid a class and use JSC::constructEmptyObject(vm, structure) with putDirectOffset
Prefer placing the subspaceFor implementation in the .cpp file rather than the header when possible

Files:

  • src/bake/BakeGlobalObject.cpp
**/*.cpp

📄 CodeRabbit inference engine (.cursor/rules/javascriptcore-class.mdc)

**/*.cpp: Include "root.h" at the top of C++ binding files to satisfy lints
Define prototype properties using a const HashTableValue array and declare accessors/functions with JSC_DECLARE_* macros
Prototype classes should subclass JSC::JSNonFinalObject, provide create/createStructure, DECLARE_INFO, finishCreation that reifies static properties, and set mayBePrototype on the Structure
Custom getters should use JSC_DEFINE_CUSTOM_GETTER, jsDynamicCast to validate this, and throwThisTypeError on mismatch
Custom setters should use JSC_DEFINE_CUSTOM_SETTER, validate this via jsDynamicCast, and store via WriteBarrier/set semantics
Prototype functions should use JSC_DEFINE_HOST_FUNCTION, validate this with jsDynamicCast, and return encoded JSValue
Constructors should subclass JSC::InternalFunction, return internalFunctionSpace in subspaceFor, set the prototype property as non-configurable/non-writable, and provide create/createStructure
Provide a setup function that builds the Prototype, Constructor, and Structure, and assigns them to the LazyClassStructure initializer
Use the cached Structure via globalObject->m_.get(globalObject) when constructing instances
Expose constructors to Zig via an extern "C" function that returns the constructor from the LazyClassStructure
Provide an extern "C" Bun____toJS function that creates an instance using the cached Structure and returns an EncodedJSValue

Files:

  • src/bake/BakeGlobalObject.cpp
**/*.{cpp,cc,cxx,h,hpp,hxx}

📄 CodeRabbit inference engine (CLAUDE.md)

Format C/C++ sources/headers with clang-format (bun run clang-format)

Files:

  • src/bake/BakeGlobalObject.cpp
🧠 Learnings (7)
📓 Common learnings
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-08-30T00:09:39.100Z
Learning: Applies to test/bake/dev/react-spa.test.ts : react-spa.test.ts should contain React SPA, react-refresh, and basic server component transform tests
📚 Learning: 2025-08-30T00:07:54.573Z
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/building-bun.mdc:0-0
Timestamp: 2025-08-30T00:07:54.573Z
Learning: To run a file, use `bun bd <file> <...args>`; never use `bun <file>` directly

Applied to files:

  • .vscode/launch.json
📚 Learning: 2025-09-07T05:41:52.563Z
Learnt from: CR
PR: oven-sh/bun#0
File: src/js/CLAUDE.md:0-0
Timestamp: 2025-09-07T05:41:52.563Z
Learning: Applies to src/js/{builtins,node,bun,thirdparty,internal}/**/*.{js,ts} : Author modules as CommonJS-style with `require(...)` and export via `export default {}` (no ESM `import`/named exports)

Applied to files:

  • packages/bun-framework-react/vendor/react-server-dom-bun/client.node.unbundled.js
  • packages/bun-framework-react/vendor/react-server-dom-bun/client.browser.js
  • packages/bun-framework-react/vendor/react-server-dom-bun/plugin.js
📚 Learning: 2025-08-30T00:09:39.100Z
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-08-30T00:09:39.100Z
Learning: Applies to test/bake/dev/css.test.ts : css.test.ts should contain CSS bundling tests in dev mode

Applied to files:

  • packages/bun-framework-react/src/client/css.ts
📚 Learning: 2025-08-30T00:09:39.100Z
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-08-30T00:09:39.100Z
Learning: Applies to test/bake/dev/react-spa.test.ts : react-spa.test.ts should contain React SPA, react-refresh, and basic server component transform tests

Applied to files:

  • packages/bun-framework-react/package.json
📚 Learning: 2025-08-30T00:12:56.803Z
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/writing-tests.mdc:0-0
Timestamp: 2025-08-30T00:12:56.803Z
Learning: Applies to test/js/node/test/** : Vendored Node.js tests under test/js/node/test/ are exceptions and do not follow Bun’s test style

Applied to files:

  • .gitattributes
📚 Learning: 2025-08-30T00:09:39.100Z
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/dev-server-tests.mdc:0-0
Timestamp: 2025-08-30T00:09:39.100Z
Learning: Applies to test/bake/dev/bundle.test.ts : bundle.test.ts should contain DevServer-specific bundling tests

Applied to files:

  • src/bake/bake.private.d.ts
  • packages/bun-types/app.d.ts
🧬 Code graph analysis (13)
packages/bun-framework-react/src/client/constants.ts (1)
packages/bun-framework-react/src/client/router.ts (1)
  • Router (11-215)
packages/bun-framework-react/src/client/root.tsx (3)
packages/bun-framework-react/src/client/app.ts (1)
  • useAppState (86-88)
packages/bun-framework-react/src/client/constants.ts (1)
  • router (3-3)
packages/bun-framework-react/src/client/lib/util.ts (1)
  • isThenable (1-3)
packages/bun-framework-react/client.tsx (4)
packages/bun-framework-react/src/client/root.tsx (1)
  • Root (11-29)
packages/bun-framework-react/src/client/app.ts (1)
  • initialRscPayloadThen (94-96)
packages/bun-framework-react/src/client/constants.ts (1)
  • router (3-3)
src/bake/hmr-module.ts (1)
  • onServerSideReload (32-32)
packages/bun-framework-react/src/client/router.ts (2)
packages/bun-framework-react/src/client/app.ts (4)
  • NonNullishReactNode (5-5)
  • AppState (23-33)
  • setAppState (82-84)
  • getAppState (90-92)
packages/bun-framework-react/src/client/css.ts (1)
  • BakeCSSManager (1-355)
packages/bun-framework-react/src/components/link.tsx (1)
packages/bun-framework-react/src/client/constants.ts (1)
  • router (3-3)
packages/bun-framework-react/vendor/react-server-dom-bun/cjs/react-server-dom-bun-client.browser.production.js (1)
packages/bun-framework-react/ssr.tsx (2)
  • constructor (163-183)
  • constructor (289-297)
packages/bun-framework-react/src/client/app.ts (1)
packages/bun-framework-react/src/client/store.ts (3)
  • Store (3-7)
  • store (13-35)
  • useStore (37-39)
packages/bun-framework-react/vendor/react-server-dom-bun/cjs/react-server-dom-bun-client.node.production.js (1)
packages/bun-framework-react/ssr.tsx (2)
  • constructor (163-183)
  • constructor (289-297)
packages/bun-framework-react/ssr.tsx (3)
packages/bun-framework-react/server.tsx (1)
  • MiniAbortSignal (238-242)
packages/bun-framework-react/src/client/root.tsx (1)
  • Root (11-29)
packages/bun-framework-react/vendor/react-server-dom-bun/server.node.unbundled.d.ts (1)
  • RenderToPipeableStreamOptions (16-23)
packages/bun-framework-react/vendor/react-server-dom-bun/cjs/react-server-dom-bun-server.node.unbundled.production.js (2)
src/node-fallbacks/buffer.js (1)
  • Buffer (136-145)
packages/bun-framework-react/ssr.tsx (2)
  • constructor (163-183)
  • constructor (289-297)
packages/bun-framework-react/vendor/react-server-dom-bun/cjs/react-server-dom-bun-server.node.production.js (1)
packages/bun-framework-react/ssr.tsx (2)
  • constructor (163-183)
  • constructor (289-297)
packages/bun-types/app.d.ts (2)
src/bake/hmr-runtime-server.ts (1)
  • RequestContext (17-17)
src/bake/hmr-module.ts (3)
  • serverManifest (28-28)
  • ssrManifest (30-30)
  • onServerSideReload (32-32)
packages/bun-framework-react/vendor/react-server-dom-bun/cjs/react-server-dom-bun-server.browser.production.js (2)
src/node-fallbacks/buffer.js (1)
  • Buffer (136-145)
packages/bun-framework-react/ssr.tsx (2)
  • constructor (163-183)
  • constructor (289-297)
🪛 Biome (2.1.2)
packages/bun-framework-react/vendor/react-server-dom-bun/cjs/react-server-dom-bun-client.node.unbundled.production.js

[error] 250-250: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 659-660: Do not add then to an object.

(lint/suspicious/noThenProperty)


[error] 746-759: This case is falling through to the next case.

Add a break or return statement to the end of this case to prevent fallthrough.

(lint/suspicious/noFallthroughSwitchClause)


[error] 920-925: This case is falling through to the next case.

Add a break or return statement to the end of this case to prevent fallthrough.

(lint/suspicious/noFallthroughSwitchClause)


[error] 921-921: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 1661-1661: Do not shadow the global "constructor" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)


[error] 1785-1785: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)

packages/bun-framework-react/vendor/react-server-dom-bun/cjs/react-server-dom-bun-client.browser.production.js

[error] 250-250: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 659-660: Do not add then to an object.

(lint/suspicious/noThenProperty)


[error] 746-759: This case is falling through to the next case.

Add a break or return statement to the end of this case to prevent fallthrough.

(lint/suspicious/noFallthroughSwitchClause)


[error] 920-925: This case is falling through to the next case.

Add a break or return statement to the end of this case to prevent fallthrough.

(lint/suspicious/noFallthroughSwitchClause)


[error] 921-921: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 1661-1661: Do not shadow the global "constructor" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

packages/bun-framework-react/vendor/react-server-dom-bun/cjs/react-server-dom-bun-client.node.production.js

[error] 250-250: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 659-660: Do not add then to an object.

(lint/suspicious/noThenProperty)


[error] 746-759: This case is falling through to the next case.

Add a break or return statement to the end of this case to prevent fallthrough.

(lint/suspicious/noFallthroughSwitchClause)


[error] 920-925: This case is falling through to the next case.

Add a break or return statement to the end of this case to prevent fallthrough.

(lint/suspicious/noFallthroughSwitchClause)


[error] 921-921: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 1661-1661: Do not shadow the global "constructor" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)


[error] 1785-1785: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)

packages/bun-framework-react/vendor/react-server-dom-bun/cjs/react-server-dom-bun-server.node.unbundled.production.js

[error] 467-467: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 532-532: Do not shadow the global "hasOwnProperty" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)


[error] 919-919: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 1147-1148: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 1821-1822: Do not add then to an object.

(lint/suspicious/noThenProperty)


[error] 2085-2085: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 2118-2118: Do not shadow the global "constructor" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)


[error] 2342-2343: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 402-402: This variable is used before its declaration.

The variable is declared here:

(lint/correctness/noInvalidUseBeforeDeclaration)


[error] 405-405: This variable is used before its declaration.

The variable is declared here:

(lint/correctness/noInvalidUseBeforeDeclaration)

packages/bun-framework-react/vendor/react-server-dom-bun/cjs/react-server-dom-bun-server.node.production.js

[error] 467-467: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 532-532: Do not shadow the global "hasOwnProperty" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)


[error] 919-919: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 1147-1148: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 1821-1822: Do not add then to an object.

(lint/suspicious/noThenProperty)


[error] 2085-2085: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 2118-2118: Do not shadow the global "constructor" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)


[error] 2342-2343: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 402-402: This variable is used before its declaration.

The variable is declared here:

(lint/correctness/noInvalidUseBeforeDeclaration)


[error] 405-405: This variable is used before its declaration.

The variable is declared here:

(lint/correctness/noInvalidUseBeforeDeclaration)

packages/bun-framework-react/vendor/react-server-dom-bun/cjs/react-server-dom-bun-server.browser.production.js

[error] 464-464: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 529-529: Do not shadow the global "hasOwnProperty" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)


[error] 916-916: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 1144-1145: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 1818-1819: Do not add then to an object.

(lint/suspicious/noThenProperty)


[error] 2082-2082: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 2115-2115: Do not shadow the global "constructor" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)


[error] 2339-2340: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 399-399: This variable is used before its declaration.

The variable is declared here:

(lint/correctness/noInvalidUseBeforeDeclaration)


[error] 402-402: This variable is used before its declaration.

The variable is declared here:

(lint/correctness/noInvalidUseBeforeDeclaration)

🪛 markdownlint-cli2 (0.18.1)
packages/bun-framework-react/README.md

1-1: Images should have alternate text (alt text)

(MD045, no-alt-text)

Comment on lines +51 to +54
window.addEventListener("popstate", async event => {
const state = typeof event.state === "number" ? event.state : undefined;
await router.navigate(location.href, state);
});

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.

⚠️ Potential issue | 🟡 Minor

Avoid unhandled rejections in popstate handler

Event listeners ignore returned Promises. Catch navigation errors to prevent "Unhandled promise rejection" noise.

-window.addEventListener("popstate", async event => {
-  const state = typeof event.state === "number" ? event.state : undefined;
-  await router.navigate(location.href, state);
-});
+window.addEventListener("popstate", event => {
+  const state = typeof event.state === "number" ? event.state : undefined;
+  void router.navigate(location.href, state).catch(console.error);
+});
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
window.addEventListener("popstate", async event => {
const state = typeof event.state === "number" ? event.state : undefined;
await router.navigate(location.href, state);
});
window.addEventListener("popstate", event => {
const state = typeof event.state === "number" ? event.state : undefined;
void router.navigate(location.href, state).catch(console.error);
});
🤖 Prompt for AI Agents
In packages/bun-framework-react/client.tsx around lines 51 to 54, the popstate
event handler awaits router.navigate but does not catch rejections, which can
produce unhandled promise rejection noise; wrap the navigation call in a
try/catch (or append .catch(...)) and log or handle errors (include context like
the location.href and state) so any navigation failure is captured and does not
surface as an unhandled rejection.

@@ -0,0 +1,10 @@
<img src="https://bun.com/logo.png" height="36" />

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.

⚠️ Potential issue | 🟡 Minor

Add alt text to the image for accessibility.

The image is missing alternative text, which is important for accessibility and SEO.

Apply this diff to add descriptive alt text:

-<img src="https://bun.com/logo.png" height="36" />
+<img src="https://bun.com/logo.png" alt="Bun Logo" height="36" />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<img src="https://bun.com/logo.png" height="36" />
<img src="https://bun.com/logo.png" alt="Bun Logo" height="36" />
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

1-1: Images should have alternate text (alt text)

(MD045, no-alt-text)

🤖 Prompt for AI Agents
In packages/bun-framework-react/README.md around lines 1 to 1, the <img> tag
lacks an alt attribute which harms accessibility and SEO; update the tag to
include a descriptive alt text such as alt="Bun logo" or alt="Bun JavaScript
runtime logo" (choose the wording that best fits the repo) so screen readers and
search engines can interpret the image; apply the change by adding the alt
attribute to the existing img element.

An implementation of the Bun Rendering API for React, with RSC (React Server Components)

1. `bun add bun-framework-react --dev`
2. Make a `pages/index.tsx` file, with a page component defualt export

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.

⚠️ Potential issue | 🟡 Minor

Fix typo in documentation.

Line 8 contains a typo: "defualt" should be "default".

Apply this diff to correct the typo:

-2. Make a `pages/index.tsx` file, with a page component defualt export
+2. Make a `pages/index.tsx` file, with a page component default export
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
2. Make a `pages/index.tsx` file, with a page component defualt export
2. Make a `pages/index.tsx` file, with a page component default export
🤖 Prompt for AI Agents
In packages/bun-framework-react/README.md around line 8, the word "defualt" is
misspelled; change it to "default" so the sentence reads "...with a page
component default export". Update the typo and save the README.

Comment thread packages/bun-framework-react/src/client/app.ts
Comment on lines +48 to +64
const link = document.createElement("link");
let entry: { promise: Promise<void> | null; link: HTMLLinkElement };

const promise = new Promise<void>((resolve, reject) => {
link.rel = "stylesheet";
link.onload = resolve.bind(null, undefined);
link.onerror = reject;
link.href = href;
document.head.appendChild(link);
}).finally(() => {
entry.promise = null;
});

entry = { promise, link };
this.cssFiles.set(href, entry);
wait.push(promise);
}

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.

🛠️ Refactor suggestion | 🟠 Major

Fix TDZ/closure hazard when setting entry.promise and link creation.

entry is referenced inside finally before assignment. It’s safe in practice but brittle. Initialize entry first to avoid TDZ-like hazards.

-        const link = document.createElement("link");
-        let entry: { promise: Promise<void> | null; link: HTMLLinkElement };
-
-        const promise = new Promise<void>((resolve, reject) => {
-          link.rel = "stylesheet";
-          link.onload = resolve.bind(null, undefined);
-          link.onerror = reject;
-          link.href = href;
-          document.head.appendChild(link);
-        }).finally(() => {
-          entry.promise = null;
-        });
-
-        entry = { promise, link };
-        this.cssFiles.set(href, entry);
-        wait.push(promise);
+        const link = document.createElement("link");
+        const entry: { promise: Promise<void> | null; link: HTMLLinkElement } = { promise: null, link };
+        this.cssFiles.set(href, entry);
+
+        entry.promise = new Promise<void>((resolve, reject) => {
+          link.rel = "stylesheet";
+          link.onload = () => resolve();
+          link.onerror = reject;
+          link.href = href;
+          document.head.appendChild(link);
+        }).finally(() => {
+          entry.promise = null;
+        });
+
+        wait.push(entry.promise);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const link = document.createElement("link");
let entry: { promise: Promise<void> | null; link: HTMLLinkElement };
const promise = new Promise<void>((resolve, reject) => {
link.rel = "stylesheet";
link.onload = resolve.bind(null, undefined);
link.onerror = reject;
link.href = href;
document.head.appendChild(link);
}).finally(() => {
entry.promise = null;
});
entry = { promise, link };
this.cssFiles.set(href, entry);
wait.push(promise);
}
const link = document.createElement("link");
const entry: { promise: Promise<void> | null; link: HTMLLinkElement } = { promise: null, link };
this.cssFiles.set(href, entry);
entry.promise = new Promise<void>((resolve, reject) => {
link.rel = "stylesheet";
link.onload = () => resolve();
link.onerror = reject;
link.href = href;
document.head.appendChild(link);
}).finally(() => {
entry.promise = null;
});
wait.push(entry.promise);
}
🤖 Prompt for AI Agents
In packages/bun-framework-react/src/client/css.ts around lines 48 to 64, the
created Promise.finally references entry before entry is assigned, which risks a
TDZ/closure hazard; initialize entry first (e.g., create entry = { promise:
null, link } after creating the link element but before constructing the
Promise) and then assign the Promise to entry.promise so the finally callback
can safely set entry.promise = null; ensure you still set
this.cssFiles.set(href, entry) before pushing the promise to wait.

Comment thread src/ast/visitExpr.zig
Comment on lines +1452 to +1456

// Note: we do not check for `use${Hook}` here because at
// this stage, we do not yet know if the file we're parsing
// is exclusively used inside a client component module
// graph.

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.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify that the server-component guard removal is intentional and has a replacement.

The note indicates that the code no longer checks for use${Hook} at this stage because "we do not yet know if the file we're parsing is exclusively used inside a client component module graph." According to the AI summary, a large conditional block enforcing an error for useState in server components was removed (not shown in the diff).

This removal could introduce a correctness issue if:

  • Client-only hooks like useState are allowed in server components without validation elsewhere.
  • The deferred check is never implemented or is incomplete.

Run the following script to verify whether there's a replacement check for client-only hooks in server components elsewhere in the codebase:

Additionally, could you confirm:

  1. Is the removal of the server-component guard intentional?
  2. Where in the codebase is the deferred check for client-only hooks in server components implemented (if at all)?
  3. Should the commented-out hook list (lines 36-48) be used for this check?

🏁 Script executed:

#!/bin/bash
# Description: Search for server component validation logic that checks for client-only hooks.

# Search for patterns related to server component validation and client-only hooks.
rg -nP --type=zig -C3 'server.*component|client.*component|useState|useEffect|client.*only.*hook' | head -100

Length of output: 5500


🏁 Script executed:

#!/bin/bash
# Print context around line 1452 in visitExpr.zig to verify removal and look for deferred checks.
FILE=$(fd visitExpr.zig)
sed -n '1440,1470p' "$FILE"

Length of output: 1714


Ensure server-component hook validation is implemented

No deferred or alternate check for client-only hooks (e.g. useState, useEffect) was found after the guard’s removal. Reintroduce the server-component hook guard here or add a validation pass later in the module-graph resolution to error on client-only hooks in server components.

🤖 Prompt for AI Agents
In src/ast/visitExpr.zig around lines 1452-1456, the removed guard that
prevented client-only hooks (e.g. useState, useEffect, useRef, useLayoutEffect,
etc.) from being used in server components is missing; restore validation by
either reintroducing the hook guard here to detect identifiers matching the
client-only hook names and emit a compile-time error with source location when
the current module/component is a server component, or implement a new
validation pass in module-graph resolution that scans parsed ASTs for these hook
identifiers and errors for any usage inside modules marked as server-only;
ensure the error message names the hook and file/line, and keep the same
semantics as the previous guard (no-op when file is confirmed client-only).

Comment thread src/bake.zig
Comment thread src/bake/bake.private.d.ts
Comment thread src/bake/BakeGlobalObject.cpp
Comment thread src/bake/client/data-view.ts

@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: 1

♻️ Duplicate comments (1)
src/bake.zig (1)

98-99: LGTM! Exception handling properly added.

The call to scope.returnIfException() at line 99 correctly addresses the concern from the previous review, ensuring any JS exceptions thrown by BakeGetDefaultExportFromModule are properly surfaced as Zig errors.

🧹 Nitpick comments (3)
src/bake.zig (3)

13-14: Consider adding a Zig wrapper for the extern function.

Per coding guidelines, extern C symbols should have a Zig-friendly wrapper method. This would improve type safety and idiomatic usage.

Example wrapper:

// External functions for module loading
extern fn BakeGetDefaultExportFromModule(global: *jsc.JSGlobalObject, key: jsc.JSValue) jsc.JSValue;

pub fn getDefaultExportFromModule(global: *jsc.JSGlobalObject, key: jsc.JSValue) jsc.JSValue {
    return BakeGetDefaultExportFromModule(global, key);
}

As per coding guidelines.


97-97: Remove unused binding.

The resolved binding is not used. Replace with _ to make the intent clear.

-                .fulfilled => |resolved| blk: {
-                    _ = resolved;
+                .fulfilled => |_| blk: {

114-114: Remove unused binding.

The err binding is not used. Replace with _ to make the intent clear.

-                .rejected => |err| {
-                    _ = err;
+                .rejected => |_| {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between d7217f26d52f44f9d10dc7b57d4aebdc26afa2b1 and c84adf8eaaaa21a54542aa26b7f5b6e71fed3e51.

📒 Files selected for processing (1)
  • src/bake.zig (8 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
src/**/*.zig

📄 CodeRabbit inference engine (.cursor/rules/building-bun.mdc)

Implement debug logs in Zig using const log = bun.Output.scoped(.${SCOPE}, false); and invoking log("...", .{})

Files:

  • src/bake.zig
**/*.zig

📄 CodeRabbit inference engine (.cursor/rules/javascriptcore-class.mdc)

**/*.zig: Declare the extern C symbol in Zig and export a Zig-friendly alias for use
Wrap the Bun____toJS extern in a Zig method that takes a JSGlobalObject and returns JSC.JSValue

**/*.zig: Format Zig files with zig-format (bun run zig-format)
In Zig, manage memory carefully with allocators and use defer for cleanup

Files:

  • src/bake.zig
🧠 Learnings (2)
📚 Learning: 2025-08-30T00:11:57.076Z
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/registering-bun-modules.mdc:0-0
Timestamp: 2025-08-30T00:11:57.076Z
Learning: Applies to src/{**/js_*.zig,bun.js/api/**/*.zig} : Use bun.JSError!JSValue for proper error propagation in JS-exposed Zig functions

Applied to files:

  • src/bake.zig
📚 Learning: 2025-08-30T00:13:36.815Z
Learnt from: CR
PR: oven-sh/bun#0
File: .cursor/rules/zig-javascriptcore-classes.mdc:0-0
Timestamp: 2025-08-30T00:13:36.815Z
Learning: Applies to src/bun.js/**/*.zig : Constructors and prototype methods should return bun.JSError!JSC.JSValue to integrate Zig error handling with JS exceptions

Applied to files:

  • src/bake.zig
🔇 Additional comments (4)
src/bake.zig (4)

32-32: LGTM! Signature change supports dynamic framework resolution.

The addition of the resolver parameter is necessary for the new dynamic framework resolution feature and is used appropriately throughout the function.


430-434: LGTM! Proper separation of concerns.

The added validation and comment correctly reflect that string framework handling has been moved to UserOptions.fromJS, and this function now expects only object-based framework definitions.


403-413: LGTM! Improved error handling.

The added null and empty path checks with descriptive error messages improve robustness and debugging experience.


78-79: Ensure pathConst() never returns null before unwrapping
At src/bake.zig:78, resolved_path.pathConst().?.text will panic if pathConst() is null—confirm that resolution always produces a valid path or handle the null case explicitly.

Comment thread src/bake.zig
Comment on lines +881 to 890
.path = bun.fs.Path.initForKitBuiltIn("bun", "app/server"),
.contents = "", // Virtual
.index = bun.ast.Index.bake_server_data,
};

pub const client_virtual_source: bun.logger.Source = .{
.path = bun.fs.Path.initForKitBuiltIn("bun", "bake/client"),
.path = bun.fs.Path.initForKitBuiltIn("bun", "app/client"),
.contents = "", // Virtual
.index = bun.ast.Index.bake_client_data,
};

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.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify all references to old virtual paths have been updated.

The virtual source paths have been changed from bake/server and bake/client to app/server and app/client. Ensure all references to the old paths throughout the codebase have been updated accordingly.


🏁 Script executed:

#!/bin/bash
# Description: Search for references to old virtual source paths

# Search for old path references
rg -n 'bake/(server|client)' --type=zig --type=js --type=ts

# Search for references to the path constants
rg -n 'server_virtual_source|client_virtual_source' --type=zig

Length of output: 895


Update remaining virtual path in codegen

  • src/codegen/bake-codegen.ts:56: change css("../bake/client/overlay.css", !!debug) to css("../app/client/overlay.css", !!debug).
🤖 Prompt for AI Agents
In src/bake.zig around lines 881-890 there are virtual path entries for
client/server; update the codegen source reference in
src/codegen/bake-codegen.ts (around line 56) where it currently uses
css("../bake/client/overlay.css", !!debug) to instead reference the real virtual
path css("../app/client/overlay.css", !!debug); modify that string only so
codegen points to "../app/client/overlay.css" and keep the rest of the call
(including the !!debug flag) unchanged.

@alii
alii marked this pull request as draft October 4, 2025 00:37
@alii alii closed this Jan 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.

4 participants