Finally using --import tsx/esm as --experimental-strip-types is too buggy (tried to fix the loader introduced too many side effects)
Enable direct TypeScript imports from node_modules using Node.js --experimental-strip-types flag without requiring a separate compilation step.
Node.js introduced the --experimental-strip-types flag which allows running TypeScript files directly without compilation. However, Node.js doesn't allow direct importing of TypeScript files from node_modules. This package provides a workaround by creating a dedicated ts_modules folder that mirrors TypeScript-enabled packages.
This project was inspired by discussions in:
- Node.js Issue #57215: Support for importing TypeScript files from node_modules
- Reddit Discussion on TypeScript publishing practices
Instead of creating individual symlinks for each package, this tool creates a single symlink called ts_modules that points to the project's node_modules directory. This simplifies the setup and maintenance process.
A custom loader intercepts module imports:
- For CommonJS: Monkey-patches Node's resolution to check
ts_modulesfirst - For ESM: Uses an experimental loader hook
When a bare import (e.g., require('my-package')) is made, the loader resolves it through the ts_modules symlink, which points to node_modules.
For directory imports, the loader looks for a defined entry file using:
- A custom
"ts:main"field in package.json - Falling back to
"main"field - Looking for
index.tsorindex.js
This ensures Node loads a file, not a directory.
# Using npm
npm install node-ts-modules
# Using Yarn
yarn add node-ts-modules-
Install the package as shown above.
-
Run your application with the appropriate loader:
For CommonJS:
# Directly with Node.js node -r @esbuild-kit/esm-loader your-script.jsFor ESM:
# Directly with Node.js node --experimental-loader=@esbuild-kit/esm-loader your-script.js
- When a bare import is encountered (e.g.,
import { something } from 'package-name'), the loader intercepts it. - The loader resolves the import through the
ts_modulessymlink, which points tonode_modules. - If the package has TypeScript source files, they can be loaded directly.
- Node.js then uses the
--experimental-strip-typesflag to strip the types and execute the TypeScript file directly.
- Requires Node.js version 22 or higher
- The
--experimental-strip-typesflag is still experimental - Not all TypeScript features are supported by the type stripping mechanism
The ts_modules directory is created at runtime and contains symlinks specific to your environment. It should not be committed to version control. Make sure to add it to your .gitignore file:
# ts-modules specific
ts_modules/
MIT