Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/solid-router/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@
"@tanstack/router-core": "workspace:*",
"@tanstack/solid-store": "^0.8.0",
"isbot": "^5.1.22",
"srvx": "^0.11.2",
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

🏁 Script executed:

#!/bin/bash
# Search for renderRouterToStream files
echo "=== Searching for renderRouterToStream files ==="
fd 'renderRouterToStream' --extension tsx --extension ts --exec head -50 {}

echo ""
echo "=== Checking sideEffects in package.json ==="
rg '"sideEffects"' packages/solid-router/package.json -A 1

Repository: TanStack/router

Length of output: 4369


🌐 Web query:

srvx npm package

💡 Result:

srvx is an npm package that provides a universal server API based on Web Platform standards (a fetch(req: Request) handler), designed to run consistently across Node.js, Deno, and Bun, with a zero-dependency core and a CLI that includes watching, logging, error handling, and static file serving. [1][2]

  • Docs / homepage: srvx.h3.dev [2]
  • Source repo: h3js/srvx on GitHub [1]
  • Latest version (seen on third-party indexes): ~0.9.x (e.g., 0.9.8). [3][4]

Quick start (CLI)

Create server.ts:

export default {
  fetch(req: Request) {
    return Response.json({ hello: "world!" });
  },
};

Run:

  • Node: npx srvx
  • Deno: deno -A npm:srvx
  • Bun: bunx --bun srvx [2][1]

Quick start (library API)

import { serve } from "srvx";

const server = serve({
  port: 3000,
  fetch() {
    return new Response("Hello!");
  },
});

await server.ready();
console.log(server.url);

[5]

Sources: [1] GitHub repo, [2] official site, [3] Socket package index, [4] jsDelivr package page, [5] Libraries.io page.


Global mutation of Response conflicts with "sideEffects": false declaration.

The code assigns globalThis.Response = FastResponse (in the solid-router Solid.js entry point), which is a side effect. However, this package.json declares "sideEffects": false on line 95. Bundlers may tree-shake the module entirely, silently dropping the Response assignment and negating the performance optimization.

Recommended fixes:

  1. Remove or set "sideEffects": true to ensure bundlers include this module.
  2. If the global mutation is unavoidable, document the constraints clearly (e.g., this must be imported early, affects all downstream code, may conflict with other Response polyfills).
  3. For the pre-1.0 srvx dependency, consider using ~0.11.2 instead of ^0.11.2 to avoid minor-version breaking changes.
🤖 Prompt for AI Agents
In `@packages/solid-router/package.json` at line 111, The package declares
"sideEffects": false but the Solid entry point mutates globalThis.Response by
assigning globalThis.Response = FastResponse, which is a side-effect that can be
tree-shaken away; update package.json to either set "sideEffects": true or
remove the flag so bundlers won't drop the module, and add a clear note in the
package README (or package.json "description"/"keywords") documenting that
importing this package mutates global Response and must be imported early and
may conflict with other polyfills; also tighten the srvx dependency from
"^0.11.2" to "~0.11.2" to avoid unintended minor-version breakage.

"tiny-invariant": "^1.3.3",
"tiny-warning": "^1.0.3"
},
Expand Down
3 changes: 3 additions & 0 deletions packages/solid-router/src/ssr/renderRouterToStream.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ import * as Solid from 'solid-js/web'
import { isbot } from 'isbot'
import { transformReadableStreamWithRouter } from '@tanstack/router-core/ssr/server'
import { makeSsrSerovalPlugin } from '@tanstack/router-core'
import { FastResponse } from 'srvx'
import type { JSXElement } from 'solid-js'
import type { ReadableStream } from 'node:stream/web'
import type { AnyRouter } from '@tanstack/router-core'

globalThis.Response = FastResponse
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

Do not mutate globalThis.Response — this is a dangerous process-wide side effect.

Overwriting globalThis.Response at module scope permanently replaces the native Response constructor for every module in the Node.js process, not just this file. This causes several problems:

  1. Unbounded blast radius — any library, middleware, or framework code that calls new Response(...) will silently get a FastResponse instead, which may not be fully compatible (e.g., instanceof Response checks, missing methods/properties).
  2. Import-time side effect — the mutation fires the moment this module is imported, even if renderRouterToStream is never called.
  3. Not reversible — there is no cleanup; the original Response is lost.
  4. Breaks TypeScript guaranteesFastResponse is not necessarily assignable to typeof Response, yet downstream code will rely on the global type.

Instead, use FastResponse directly at the call site on line 57:

Proposed fix
 import { FastResponse } from 'srvx'
-
-globalThis.Response = FastResponse

 ...

-  return new Response(responseStream as any, {
+  return new FastResponse(responseStream as any, {
     status: router.state.statusCode,
     headers: responseHeaders,
   })
🤖 Prompt for AI Agents
In `@packages/solid-router/src/ssr/renderRouterToStream.tsx` at line 10, Do not
overwrite globalThis.Response; remove the module-scope assignment
"globalThis.Response = FastResponse" and instead use FastResponse directly where
a Response is constructed inside renderRouterToStream (replace uses of the
global Response/new Response(...) in that function with new FastResponse(...) or
return FastResponse instances). Ensure any type/instance checks that expect the
native Response are adjusted to check for FastResponse or use a small
compatibility wrapper inside renderRouterToStream rather than mutating
globalThis.


export const renderRouterToStream = async ({
request,
router,
Expand Down
33 changes: 18 additions & 15 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading