Node.js throws ERR_UNKNOWN_FILE_EXTENSION when trying to import or execute files with unrecognized extensions. This commonly occurs with TypeScript files (.ts), Python files (.py), or other non-JavaScript file types that Node.js cannot natively process.
This error occurs when Node.js encounters a file extension it doesn't know how to handle during module resolution or execution. By default, Node.js only recognizes JavaScript file extensions (.js, .mjs, .cjs) and JSON files (.json). When you try to import, require, or execute a file with any other extension—such as .ts (TypeScript), .py (Python), .jsx (React), or extensionless files—Node.js throws this error. The error is particularly common when: - Running TypeScript files directly without transpilation - Using ES modules (ESM) with "type": "module" in package.json - Attempting to execute files from other programming languages - Working with custom file extensions without proper loader configuration Node.js's module system requires explicit configuration through custom loaders or transpilers to handle non-standard file extensions. The error message typically includes the problematic extension and the file path where Node.js encountered the unknown extension.
Check the error message to identify which file extension is problematic:
# The error will show something like:
Error: [ERR_UNKNOWN_FILE_EXTENSION] Unknown file extension '.ts' for /path/to/file.tsIf the extension is .ts, .tsx, or .jsx, you need a TypeScript/JSX transpiler. If it's .py, .java, or another language, you're trying to execute non-JavaScript code with Node.js.
Modern Node.js versions work better with tsx, which has better ESM support:
# Install tsx
npm install --save-dev tsx
# Run TypeScript files directly
npx tsx src/index.ts
# Or add to package.json scripts
"scripts": {
"dev": "tsx src/index.ts",
"start": "node dist/index.js"
}tsx provides seamless TypeScript execution without complex configuration and works reliably with Node.js 18+.
If you must use ts-node with "type": "module", configure tsconfig.json:
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "node",
"esModuleInterop": true,
"target": "ES2020"
},
"ts-node": {
"esm": true,
"experimentalSpecifierResolution": "node"
}
}Then run with the ESM loader:
node --loader ts-node/esm src/index.tsNote: experimentalSpecifierResolution is deprecated in newer Node.js versions.
If you don't specifically need ES modules, removing "type": "module" from package.json can resolve the issue:
{
"name": "your-project",
// Remove or comment out this line:
// "type": "module",
"scripts": {
"dev": "ts-node src/index.ts"
}
}Then ts-node will work in CommonJS mode, which has fewer compatibility issues.
The most reliable approach is to transpile TypeScript to JavaScript first:
# Compile TypeScript
npx tsc
# Run the compiled JavaScript
node dist/index.jsIn package.json:
{
"scripts": {
"build": "tsc",
"start": "node dist/index.js",
"dev": "tsx src/index.ts"
}
}This separates development (tsx) from production (compiled JS), avoiding runtime transpilation issues.
If you need to import non-JavaScript files (.json, .graphql, etc.), use Node.js loaders:
// For JSON in ESM mode (Node.js 17.5+)
import config from './config.json' assert { type: 'json' };
// Or with import attributes (newer syntax)
import config from './config.json' with { type: 'json' };For other file types, you'll need custom loaders or build-time transformations (webpack, vite, etc.).
Node.js Version Considerations: The ERR_UNKNOWN_FILE_EXTENSION behavior changed significantly between Node.js versions. Node.js 20+ has stricter ESM enforcement, making ts-node compatibility more challenging. If you're stuck on an older Node.js version, consider upgrading or using nvm to test different versions.
Custom Loaders: Node.js supports custom loaders via the --loader flag, but this API is experimental and subject to change. Custom loaders can handle arbitrary file extensions, but they require careful implementation and maintenance.
Performance Implications: Running TypeScript directly with tsx or ts-node adds transpilation overhead. For production environments, always compile to JavaScript first using tsc. Development tools like tsx use esbuild internally for fast transpilation, but it skips type checking—run tsc separately for type safety.
Python and Other Languages: The example error shows a .py file, which indicates a fundamental misunderstanding—Node.js cannot execute Python code. If you need to run Python from Node.js, use child_process to spawn a Python interpreter, or consider using a polyglot runtime like GraalVM.
ESM vs CommonJS: The "type": "module" setting in package.json makes Node.js treat all .js files as ES modules. This requires explicit file extensions in imports (import './file.js' not import './file') and can cause issues with tools designed for CommonJS. Consider using .mjs extensions for ES modules if you need to mix both module systems.
Alternative Solutions: For modern projects, consider using build tools like Vite, Next.js, or Remix that handle TypeScript transpilation transparently. These frameworks abstract away Node.js's module system complexities and provide better developer experience.
Error: Listener already called (once event already fired)
EventEmitter listener already called with once()
Error: EACCES: permission denied, open '/root/file.txt'
EACCES: permission denied
Error: Invalid encoding specified (stream encoding not supported)
How to fix Invalid encoding error in Node.js readable streams
Error: EINVAL: invalid argument, open
EINVAL: invalid argument, open
TypeError: readableLength must be a positive integer (stream config)
TypeError: readableLength must be a positive integer in Node.js streams