tsc requirement of using .js extensions in source code to proper TypeScript extensions, making your code runnable by Node.js and other standards-compliant runtime environments.
What It Does
Transforms import specifiers to use correct file extensions:- No extension →
.ts,.cts,.mts,.d.ts,.d.cts,.d.mts .js→.ts.cjs→.cts.mjs→.mts.js→.d.ts,.d.cts,.d.mts(for type-only imports)- Directory imports →
./directory/index.ts
Usage
Examples
Basic Import Corrections
Before
After
Supported Cases
- Missing extensions - Adds correct
.ts,.cts,.mts, or.d.tsextensions - Incorrect extensions - Changes
.jsto.ts,.cjsto.cts,.mjsto.mts - Package.json subpath imports - Respects
#imports defined in package.json - tsconfig paths - Resolves path aliases via
@nodejs-loaders/alias - Directory specifiers - Converts
./dirto./dir/index.ts - Type-only exports - Automatically adds
typekeyword where appropriate
TypeScript Configuration
After running this codemod, update yourtsconfig.json:
- Using tsc for Compilation
- Using tsc for Type-Checking Only
Enable
rewriteRelativeImportExtensions in your tsconfig:tsconfig.json
Monorepo Usage
For monorepos, run the codemod within each workspace for best results:Safety Features
- File existence verification - Only applies changes when target files exist
- Ambiguity detection - Skips cases where multiple valid targets exist (e.g., both
foo.tsandfoo.js) - Error logging - Reports ambiguous cases for manual review
- Continues on errors - Skips problematic imports and continues processing
Type Import Keywords
Node.js requires thetype keyword on type-only imports. While this codemod handles most cases, some scenarios may require additional tooling:
use-import-typevia Biometypescript/no-import-type-side-effectsvia oxlintconsistent-type-importsvia typescript-eslint
Why This Matters
TypeScript historically required.js extensions in import statements even when importing .ts files, creating a mismatch between source code and actual files. With Node.js native ESM support:
- Import specifiers must match actual file names
- Runtime environments need correct extensions to resolve modules
- This enables running TypeScript directly with loaders or transpilers
- Aligns with ECMAScript module standards