Skip to content
Latchkey

Node "ERR_UNKNOWN_FILE_EXTENSION: Unknown file extension .ts" in CI

Node ESM only knows how to load .js, .mjs, and .cjs. Pointing it at a .ts entry without a TypeScript loader (or older Node without --experimental-strip-types) throws ERR_UNKNOWN_FILE_EXTENSION.

What this error means

Running node src/index.ts or node --loader ts-node/esm fails with "TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension \".ts\" for /app/src/index.ts".

node
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for
/app/src/index.ts
    at Object.getFileProtocolModuleFormat (node:internal/modules/esm/get_format:160:9)

Common causes

No TypeScript loader registered for ESM

The ESM resolver has no hook for .ts, so without a loader Node cannot determine the module format.

Node version below the strip-types support

Native .ts execution needs a recent Node (--experimental-strip-types on 22.6+, default on 23.6+); older runners cannot run .ts directly.

How to fix it

Run via tsx, which handles .ts in ESM

tsx registers a loader so .ts files run without a separate build step.

Terminal
npm install -D tsx
npx tsx src/index.ts

Or enable native type stripping on Node 22.6+

Recent Node can strip TypeScript types at run time with a flag.

Terminal
node --experimental-strip-types src/index.ts

How to prevent it

  • Use tsx or a build step to run TypeScript under ESM.
  • Pin a Node version that supports your chosen TS-run strategy.
  • Avoid passing raw .ts to a plain node invocation.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →