TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for /app/src/index.ts

Node.js · updated 2026-11-03

Thrown at startup when node (or ts-node in ESM mode) loads a .ts file in a package with "type": "module". Plain node does not know how to load TypeScript unless type stripping is available and on for that file.

node:internal/modules/esm/get_format:189
  throw new ERR_UNKNOWN_FILE_EXTENSION(ext, filepath);
        ^

TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for /app/src/index.ts
    at Object.getFileProtocolModuleFormat [as file:] (node:internal/modules/esm/get_format:189:9)
    at defaultGetFormat (node:internal/modules/esm/get_format:232:36) {
  code: 'ERR_UNKNOWN_FILE_EXTENSION'
}

Quick fix

Pick one way to run TypeScript and use it everywhere: run the file with tsx (npx tsx src/index.ts), compile with tsc and run the .js output in production, or use a Node version with built-in type stripping. ts-node in ESM projects needs its ESM loader, which is where this error usually comes from.

  1. Check package.json: "type": "module" makes .ts files load as ES modules.
  2. For development and scripts, replace ts-node with tsx: "dev": "tsx watch src/index.ts".
  3. For production, build with tsc and run node dist/index.js, so no loader is needed at runtime.
  4. On a recent Node.js, plain node can run .ts files by stripping types; check your version supports it and that you use only erasable syntax.
  5. If you must keep ts-node, run it with its ESM loader (node --loader ts-node/esm) and matching tsconfig settings.
json
{
  "type": "module",
  "scripts": {
    "dev": "tsx watch src/index.ts",
    "build": "tsc -p tsconfig.json",
    "start": "node dist/index.js"
  },
  "devDependencies": { "tsx": "^4", "typescript": "^5" }
}

Why it happens

ts-node in an ESM project

ts-node registers itself for CommonJS by default. With "type": "module", Node uses the ESM loader, which does not know .ts until a loader is added.

Running .ts in production without a build

A start script that points at src/index.ts works locally under a dev tool and fails in a container that runs plain node.

A Node version without type stripping

Older Node versions cannot load .ts at all, so the same command works on one machine and fails on another with a different Node version.

Other fixes

  • Pin the Node version (.nvmrc, engines, the Docker base image) so dev and production behave the same.
  • Bun and Deno run TypeScript directly if you are open to a different runtime.

Same error, other wording

  • TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".tsx" for /app/src/App.tsx
  • TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".mts" for /app/scripts/seed.mts

Let your coding agent catch the next one

Runheed records this error in production with the stack trace, the breadcrumbs before it and the agent session that shipped the code, and serves it to Claude Code, Cursor or any MCP client. With it connected, you can ask:

> Find the ERR_UNKNOWN_FILE_EXTENSION errors, show me which command and Node version start the app in each environment, and switch to one approach: tsx for dev scripts and a compiled build for production.

Plans from $29/moSee what your agent readsSee the setupCancel any time from the billing portal

Related errors

References: Node.js docs: running TypeScript natively, tsx docs