Skip to content

bug: shared adapter type chunk breaks tsc for Node-only consumers without skipLibCheck #284

Description

@cany748

Environment

srvx 0.12.4, TypeScript 7.0.2, @types/node 26, Node 24

Reproduction

tsconfig.json: {"module": "NodeNext", "target": "esnext", "lib": ["esnext"], "strict": true}

import {staticMiddleware} from "srvx/static";

export const mw = staticMiddleware({dir: "./public"});

npx tsc --noEmit → 13 errors, all inside srvx's own .d.mts.

Describe the bug

dist/_chunks/types.d.mts is one shared chunk pulled in by every entrypoint, including the Node-only srvx/node and srvx/static. It imports aws-lambda, bun and @cloudflare/workers-types, and references the Deno namespace and FetchEvent. All of those are devDependencies of srvx, so consumers never receive them — a Node-only project cannot type-check without skipLibCheck: true, even though it targets none of those runtimes.

skipLibCheck is repo-wide, so working around one dependency also stops checking every other dependency's types.

Separately, dist/adapters/node.d.mts:43 uses the global BodyInit, which @types/node does not provide and which needs "lib": ["dom"]. Importing it from undici-types would avoid that.

Additional context

Possible fixes, in order of preference:

  1. Split the type chunk per adapter, so Node-only entrypoints stop referencing Bun/Deno/Workers/Lambda types. This looks like the root fix — the coupling comes from how .d.mts is bundled, not from a real dependency.
  2. Declare @types/aws-lambda, @types/bun, @cloudflare/workers-types and @types/deno as peerDependencies with peerDependenciesMeta: {"optional": true}.
  3. Ship fallback ambient declarations when those packages are absent.

Happy to open a PR for (1) if you agree with the direction.

Logs

dist/_chunks/types.d.mts(4,22):   error TS2307: Cannot find module 'aws-lambda' or its corresponding type declarations.
dist/_chunks/types.d.mts(6,22):   error TS2307: Cannot find module 'bun' or its corresponding type declarations.
dist/_chunks/types.d.mts(7,21):   error TS2307: Cannot find module '@cloudflare/workers-types' or its corresponding type declarations.
dist/_chunks/types.d.mts(196,10): error TS2503: Cannot find namespace 'Deno'.
dist/_chunks/types.d.mts(244,14): error TS2503: Cannot find namespace 'Deno'.
dist/_chunks/types.d.mts(288,11): error TS2503: Cannot find namespace 'Deno'.
dist/_chunks/types.d.mts(288,33): error TS2503: Cannot find namespace 'Deno'.
dist/_chunks/types.d.mts(301,30): error TS2307: Cannot find module 'cloudflare:workers' or its corresponding type declarations.
dist/_chunks/types.d.mts(301,108): error TS2307: Cannot find module 'cloudflare:workers' or its corresponding type declarations.
dist/_chunks/types.d.mts(308,12): error TS2304: Cannot find name 'FetchEvent'.
dist/_chunks/types.d.mts(357,51): error TS2503: Cannot find namespace 'Deno'.
dist/_chunks/types.d.mts(357,73): error TS2503: Cannot find namespace 'Deno'.
dist/adapters/node.d.mts(43,15):  error TS2304: Cannot find name 'BodyInit'.

Activity

  1. pi0 commented on Jul 29, 2026

    @pi0
    Member

    Thanks for issue. I just spawned an agent to go with B, it might fix some other relavant issues we had.

    BTW nice work on Koenkk/zigbee2mqtt#32685, LMK if could help anyhow ;)

  2. added 4 commits that reference this issue on Jul 29, 2026
    9706eb6
    114ef10
    f96a59a
    7f15078
  3. cany748 commented on Jul 30, 2026

    @cany748
    ContributorAuthor

    Verified against the pkg.pr.new build of #287: 12 of the 13 errors are gone. The aws-lambda / bun / @cloudflare/workers-types / cloudflare:workers imports and the Deno / FetchEvent references all resolve now.

    One reference of the same kind is left, in the inlined Bun types:

    dist/_chunks/types.d.mts(59,15): error TS2304: Cannot find name 'HeadersInit'.
    
    // dist/_chunks/types.d.mts:57-60
    /** Upgrade an incoming request to a WebSocket connection. */
    upgrade(request: Request, options?: {
      headers?: HeadersInit;
      data?: any;
    }): boolean;

    @types/node does not declare HeadersInit — only Headers itself is ambient — so this still requires lib: ["dom"], which is what ResponseBody was introduced to avoid. Deriving it the same way works; verified with lib: ["esnext"], @types/node 26 and TypeScript 7.0.2, tsc clean:

    /**
     * Headers accepted by the runtime `Headers` constructor (`HeadersInit`).
     *
     * Derived from the ambient `Headers` so that it does not require `lib: ["dom"]`.
     */
    type HeadersInit = NonNullable<ConstructorParameters<typeof globalThis.Headers>[0]>;

    It accepts string[][], Record<string, string> and Headers, matching the DOM/undici definition. Name is yours to pick, of course — ResponseBody sets the precedent.

    With that one line, srvx type-checks for a Node-only consumer with no skipLibCheck and no extra type packages. Happy to send it as a PR.

  4. pi0 commented on Jul 30, 2026

    @pi0
    Member

    Landed in https://github.com/h3js/srvx/releases/tag/v0.12.5 just saw your last message feel free to drop a PR for inlining HeadersInit but also i guess it is fair that any consumer project require node and dom standard types.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions