Skip to content
Latchkey

ts-node "register" Errors - Fix ESM vs CJS Registration in CI

ts-node has two registration paths: a CommonJS require/-r ts-node/register hook, and an ESM loader. Using the CJS hook for an ESM project (or vice versa) produces import syntax errors or unknown-extension failures because the wrong transformer is active.

What this error means

Running TypeScript via ts-node fails with Cannot use import statement outside a module, ERR_UNKNOWN_FILE_EXTENSION, or an ESM loader error. The registration mode (CJS register vs ESM loader) does not match the project’s "type" and tsconfig module setting.

ts-node output
# ESM project registered with the CJS hook:
SyntaxError: Cannot use import statement outside a module
# or CJS project run through the ESM loader:
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts"

Common causes

CJS register used for an ESM project

A package with "type": "module" (or ESM tsconfig) run with -r ts-node/register uses the CommonJS hook, which cannot handle import syntax, so it fails to parse.

ESM loader used for a CJS project, or version skew

Pointing the ESM loader at a CommonJS setup - or mismatching ts-node and TypeScript/Node versions - leaves files unhandled, yielding unknown-extension errors.

How to fix it

Match the registration to the module system

Use the ESM loader for ESM projects and the register hook for CJS.

Terminal
# CommonJS project
node -r ts-node/register src/index.ts

# ESM project ("type":"module")
node --loader ts-node/esm src/index.ts   # older Node
# or the current register-based form ts-node documents

Align versions and config

  1. Keep ts-node, TypeScript, and Node versions compatible.
  2. Set tsconfig module/moduleResolution to match the chosen runtime (CJS vs NodeNext/ESM).
  3. Consider tsx as a simpler single-mode alternative if the dual-mode setup is fragile.

How to prevent it

  • Use one registration mode that matches the project’s module system.
  • Keep ts-node/TypeScript/Node versions aligned.
  • Make tsconfig module settings consistent with package "type".

Related guides

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