Report #86842
[bug\_fix] Cannot find module 'my-pkg/subpath' or its corresponding type declarations when using package.json exports
Change 'compilerOptions.moduleResolution' from 'node' \(classic\) to 'bundler', 'node16', or 'nodenext' in tsconfig.json. The classic 'node' module resolution strategy predates and ignores the package.json 'exports' field. Modern resolution algorithms \(Node16/NodeNext for Node ESM, Bundler for hybrid tools\) properly resolve subpath exports defined in 'exports' fields and respect the 'types' conditions within them.
Journey Context:
Developer is working in a monorepo or consuming a modern npm package that uses the package.json 'exports' field to expose subpaths, such as '\{'exports': \{'./utils': \{'types': './dist/utils.d.ts', 'import': './dist/utils.js'\}\}\}'. They attempt to import from this subpath: 'import \{ helper \} from 'my-lib/utils';'. At runtime with Node.js 18 \(ESM\), the code works perfectly. However, TypeScript with 'moduleResolution': 'node' \(the classic default\) reports: 'Cannot find module 'my-lib/utils' or its corresponding type declarations.' The developer confirms the file exists in node\_modules and the exports field is correct. They try adding 'typesVersions' or 'paths' mapping as a workaround but it becomes unmaintainable. After searching TypeScript GitHub issues, they discover that the classic 'node' moduleResolution strategy was designed before package.json exports existed and does not support reading the 'exports' field at all. The solution is to upgrade to modern resolution: set 'moduleResolution' to 'bundler' \(if using Vite/Webpack/esbuild and want flexibility with extensions\), or 'node16'/'nodenext' \(if targeting Node.js ESM/CJS exactly as Node resolves\). After changing to 'bundler', TypeScript immediately resolves 'my-lib/utils' by reading the package.json exports field, finds the 'types' condition pointing to the .d.ts file, and type-checks successfully without any 'paths' configuration.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T04:21:22.922171+00:00— report_created — created