Node tsx/ts-node Runtime Resolution Error in CI - Fix the TypeScript Loader
tsx and ts-node run TypeScript through a custom loader. Resolution errors appear when the loader, the module setting, and import extensions disagree.
What this error means
Running TS directly with tsx or ts-node fails in CI with a resolution error (cannot find module or unknown extension) even though tsc compiles the project fine.
TypeError [ERR_MODULE_NOT_FOUND]: Cannot find module
'/home/runner/work/app/app/src/utils' imported from
/home/runner/work/app/app/src/index.ts
at finalizeResolution (node:internal/modules/esm/resolve:264:11)Common causes
Extensionless imports under ESM resolution
In ESM mode the loader does not append .ts/.js, so a bare relative import fails to resolve.
A loader and tsconfig module mismatch
The ts-node/tsx loader expects one module system while tsconfig targets another, so resolution diverges from tsc.
How to fix it
Use tsx, which handles extensions
- Run the TypeScript entry through tsx in CI.
- Use the same command locally.
- run: npx tsx src/index.tsAlign ts-node ESM settings
- Enable ts-node ESM support and allow .ts extensions in imports.
- Match the tsconfig module setting to the loader mode.
// tsconfig.json
"ts-node": { "esm": true, "experimentalSpecifierResolution": "node" }How to prevent it
- Pick one TypeScript runner and keep its loader, the tsconfig module setting, and import-extension style consistent between local dev and CI.