npm package: @flightdev/loader
Description: Optional ESM loader for TypeScript extension resolution in Node.js
Author: Flight Contributors
Latest version: 0.2.1

# @flightdev/loader

Optional ESM loader for TypeScript extension resolution in Node.js. This package enables seamless imports without explicit file extensions.

## When to Use

This package is **optional**. Modern Node.js versions (22.18+) include native TypeScript support. Use this loader only if:

- You are on Node.js < 22.18
- You need custom extension resolution behavior
- You want consistent resolution across all Node.js versions

## Installation

```bash
npm install @flightdev/loader
```

## Usage

### Option 1: Node.js Native TypeScript (Recommended)

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
```

### Option 2: Flight Loader

For older Node.js versions or custom resolution:

```bash
node --import @flightdev/loader/register ./server.js
```

### Option 3: tsconfig.json Configuration

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+)

### Extension Priority

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.

### Vite

```typescript
// Automatic - resolve.extensions is configured by default
import { defineConfig } from '@flightdev/core';
import { vite } from '@flightdev/bundler-vite';

export default defineConfig({
    bundler: vite(),
});
```

### esbuild

```typescript
// Automatic - resolveExtensions is configured by default
import { esbuild } from '@flightdev/bundler-esbuild';
```

### Rolldown

```typescript
// Automatic - resolve.extensions is configured by default
import { rolldown } from '@flightdev/bundler-rolldown';
```

## Requirements

- Node.js >= 20.0.0
- For native TypeScript: Node.js >= 22.18.0

## Related

- [Module Resolution Guide](../../docs/module-resolution.md)
- [RSC Boundaries](../../docs/rsc-boundaries.md)
- [TypeScript Configuration](../../docs/typescript.md)

## License

MIT