Optional ESM loader for TypeScript extension resolution in Node.js
npm install @flightdev/loaderbash
npm install @flightdev/loader
`
Usage
$3
Node.js v22.18+ includes native TypeScript type stripping:
`bash
v22.18+ (enabled by default in v23.6+)
node --experimental-strip-types ./server.ts
v25.2+ (stable, no flag needed)
node ./server.ts
`
$3
For older Node.js versions or custom resolution:
`bash
node --import @flightdev/loader/register ./server.js
`
$3
Configure TypeScript to rewrite imports during compilation:
`json
{
"compilerOptions": {
"module": "nodenext",
"moduleResolution": "nodenext",
"rewriteRelativeImportExtensions": true,
"erasableSyntaxOnly": true,
"verbatimModuleSyntax": true
}
}
`
The rewriteRelativeImportExtensions option (TypeScript 5.7+) rewrites .ts imports to .js in output.
How It Works
The loader implements Node.js module customization hooks to:
1. Resolve - Find files without explicit extensions by trying .ts, .tsx, .js, etc.
2. Load - Pass TypeScript files to Node.js native type stripping (v22.18+)
$3
When importing without an extension (e.g., import { x } from './utils'):
1. ./utils.ts
2. ./utils.tsx
3. ./utils.mts
4. ./utils.js
5. ./utils.jsx
6. ./utils.mjs
7. ./utils.json
8. ./utils/index.ts
9. ./utils/index.js
API
`typescript
import {
supportsNativeTypeScript,
getRecommendedFlags,
resolveWithExtensions,
RESOLVE_EXTENSIONS
} from '@flightdev/loader';
// Check Node.js capability
if (supportsNativeTypeScript()) {
// Node.js can handle TypeScript natively
}
// Get recommended CLI flags
const flags = getRecommendedFlags();
// ['--experimental-strip-types'] or [] for v25+
// Resolve specifier with extensions
const paths = resolveWithExtensions('./utils');
// ['./utils.ts', './utils.tsx', './utils.mts', ...]
`
Bundler Integration
Flight's bundlers (Vite, esbuild, Rolldown) include automatic extension resolution. This loader is only needed for runtime Node.js execution outside of the bundler.
$3
`typescript
// Automatic - resolve.extensions is configured by default
import { defineConfig } from '@flightdev/core';
import { vite } from '@flightdev/bundler-vite';
export default defineConfig({
bundler: vite(),
});
`
$3
`typescript
// Automatic - resolveExtensions is configured by default
import { esbuild } from '@flightdev/bundler-esbuild';
`
$3
`typescript
// Automatic - resolve.extensions is configured by default
import { rolldown } from '@flightdev/bundler-rolldown';
``