Drop-in replacement for the JS-native import(..)
but works with TypeScript
files.
- You have a running
node.js
process, and you want to import.ts
file from it - BUT you realize you can't do
import './myfile.ts'
,require('./myfile.ts')
orawait import('./myfile.ts')
. - And you DON'T want an additional compilation step before the process starts
This is where import-single-ts
comes in. It allows you do
await importSingleTs('./myfile.ts')
with no extra steps needed.
A common example would be defining things like configuration or setup in a
type-safe (ts) environment. Think vite.config.ts
, webpack.config.ts
, etc.
-
Make sure you've installed the
esbuild
(it's a peer dependency) -
import { importSingleTs } from 'import-single-ts'; // or for cjs: const { importSingleTs } = require('import-single-ts'); // ... await importSingleTs('./some.ts'); // place where you need it
It has the same API as the native dynamic import —
import()
*.* With some optional extras (see below).
- 🔄 Drop-in replacement for
import()
— no learning curve, you can just replace the dynamicawait import('./some.js')
calls withawait importSingleTs('./some.ts')
and it will just work as expected. - ⚡ Fast — uses
esbuild
internally and learns from the best (vite
's & esbuild plugins' source code) - 📐 Only compiles the minimum — The
.ts
file being loaded may have multiple imports, which can, in turn, have more imports at any depth. Any imported files, whichnode
can run by itself, are not compiled. Instead, they are loaded from their original path which means they are kept in the internal node module cache and there won't be duplicate module executions if they are imported again. - 🚀 No dependencies + 1 peer dependency of
esbuild
- 🧩️ Customizable import resolution — it exposes
options used in
esbuild
, so you can provide things like custom conditions for conditional exports, aliases, etc. Simply pass in a second argument like so:await importSingleTs('./some.ts', { conditions: ['mycompany-dev'], alias: { a: "b" }, ... })
- 💻️ Node.js REPL is supported as well
- ⛔️ Not intended for
bun
— TypeScript is supported out of the box inbun
, no need to use this package. - ⛔️ Not intended for
Windows
— it's not tested onWindows
and I won't be able to dedicate extra time to debug problems there.
If this makes your work easier, consider becoming a sponsor.
- I wanted to load up the exports from
.ts
file and use it as a type-safe config. There didn't seem to be an easy way to do that. - I looked into
vite
's internal logic that deals with loading upvite.config.ts
file. Before settling on usingesbuild
I wasn't sure if there was a better way to do compile on-the-fly. When I saw vite's approach I was relieved that looks like the only way, and I've also adapted pieces of their config handling code - I also researched
esbuild
node-resolve plugin. This was helpful to quickly glanceesbuild
plugin system. Sadly this relies on theresolve
package which doesn't supportpackage.json
"exports" at all. - I noticed that
node
require.extensions
is deprecated. They actually recommend compiling ahead of time which is what this package does.
ts-import
— it internally usestsc
, so loading up a file is slow. Another problem oftsc
is it can run only for a single project, so if you are in a monorepo environment, and you depend on typescript files from other projects it won't work as expected.
- replace
enhanced-resolve
when web-infra-dev/oxc ports it to Rust
- It's build as
cjs
but can be used in bothCJS
andESM
environments. That's because inmjs
can't use stack trace to figure out the directory whereimportSingleTs
was called from: nodejs/node#46992