Skip to content

viem _types/ dist folder missing {"type":"module"} marker → declarations resolve as CommonJS under nodenext (TS1479 / TS1541) #4843

Description

@javadtavakoli

Package version

viem@2.55.2 (latest at time of writing)

Summary

viem ships an explicit module-type marker for its JS output folders but not for its type-declaration folder:

folder package.json "type"
_esm/ "module"
_cjs/ "commonjs"
_types/ missing

Because the root package.json has no "type" field (defaults to commonjs), TypeScript under module/moduleResolution: nodenext determines that every .d.ts in _types/ is a CommonJS module. But those files use ESM import type / export syntax, so they are treated as CJS files importing ESM — which errors:

node_modules/viem/_types/accounts/index.d.ts(2,30): error TS1479:
  The current file is a CommonJS module whose imports will produce 'require' calls; however, the
  referenced file is an ECMAScript module and cannot be imported with 'require'. ...
node_modules/viem/_types/accounts/types.d.ts(1,41): error TS1541:
  Type-only import of an ECMAScript module from a CommonJS module must have a 'resolution-mode' attribute.

Note this survives viem's own CI because viem type-checks its source under nodenext, never its emitted _types/ as resolved through the package exports map ("types": "./_types/index.d.ts"). The defect only appears to consumers.

Reproduction

mkdir viem-repro && cd viem-repro
npm init -y && npm pkg set type=module
npm i viem@2.55.2 typescript@5.7.3 @types/node

index.ts:

import { createPublicClient, http } from "viem";
export const client = createPublicClient({ transport: http() });

tsconfig.json:

{ "compilerOptions": { "module": "nodenext", "moduleResolution": "nodenext", "strict": true, "noEmit": true, "skipLibCheck": false } }
npx tsc --noEmit
# -> ~160 errors: TS1541 (146), TS1479 (12), TS1542 (2), all inside node_modules/viem/_types/**

The fix (verified)

Adding the missing marker to the emitted types folder:

echo '{"type":"module"}' > node_modules/viem/_types/package.json

reduces the error count from 160 → 12. The one-line marker eliminates all 146 TS1541 and 2 TS1542.

The remaining 12 TS1479 all originate from viem's bundled copy of ox (viem/node_modules/ox, 0.14.x), which has the same missing-marker problem. Standalone ox@1.0.0 already fixed this (root "type":"module", output moved to dist/), so bumping viem's bundled ox — or shipping the marker in ox's 0.14.x line — closes the rest.

Suggested fix

  1. Emit a _types/package.json containing {"type":"module"} as part of the build (mirroring _esm/_cjs).
  2. Update the bundled ox to a version that ships the same marker.

Why this matters

Library authors that re-export viem types with declaration: true cannot use skipLibCheck to hide this — the CJS/ESM mismatch propagates into their emitted declarations, and they in turn cannot force skipLibCheck on their own users.

Prior art

Related older reports (#244, #1053, #1254) were closed against viem v1 with different repro shapes; this is a fresh, minimal reproduction against 2.55.2 with the specific missing-marker root cause and a verified one-line fix.

Environment

  • TypeScript 5.7.3, module/moduleResolution: nodenext, strict, skipLibCheck: false

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions