How to run TypeScript natively in Node.js with TSX

Lucas Santos - Nov 28 '23 - - Dev Community

Who hasn't wondered how runtimes like Deno can run TypeScript natively? When will it come to Node? When will we be able to run native TypeScript anywhere?!

Well, while the idea of running TS natively, without a compilation process, is still far off, we can run TypeScript files directly in Node.js without any compilation steps, these are called loaders

Loaders

Loaders are functions that act as hooks between reading a module and executing it, for example, many people are used to using ts-node or ts-node-dev.

Both of these packages are loaders, they receive the files that will be loaded by the runtime and can perform actions on them, in our case, the action is to compile the file from TypeScript to JavaScript.

You can see more about this functionality in the official documentation, including using the transpiling example itself.

TSX

TSX is the newest and most improved version of our ts-node, using ESBuild to transpile TS files to JS very quickly.
The most interesting part is that TSX was developed to be a complete replacement for Node, so you can actually use TSX as a TypeScript REPL, if you install it globally with npm i -g tsx, just run tsx in your terminal and you can write TSX natively.
But what's even cooler is that you can load TSX for all TypeScript files using --loader tsx when you run your file. For example, let's say we have this file called index.ts:

export function main(a: number, b: number) {
    console.log(a**b)
}

main(5,5)
Enter fullscreen mode Exit fullscreen mode

If we run the tsx index.ts command, we'll get an output of 3125, even without any project defined.
tsx also has a watch mode that can be run with tsx watch <file>, to watch for changes to a file.

TSX as a loader

Running a file (or all its files) through a loader is as simple as creating a start script in your package.json with the following content:

node --loader tsx index.ts
Enter fullscreen mode Exit fullscreen mode

And run as npm start.

Using TSX as a loader does not allow it to be used with any other option, such as watch.

Extending the functionality

One of the things we've been able to do since version 20.6 of Node is to directly load environment configuration files present in .env files. But how can we use both the loader and the configuration files?

Node also reads an environment variable called NODE_OPTIONS which allows you to string all the options that Node will receive, for example NODE_OPTIONS='--loader tsx.

Since we can't pass the --env-file .env option as one of the NODE_OPTIONS options, we can load the loader from it and pass the configuration file in the main command:

NODE_OPTIONS='--loader=tsx' node --env-file=.env index.ts
Enter fullscreen mode Exit fullscreen mode

Try running this command around in your projects to make development easier!

Important: Loading TS files directly from disk and compiling with loaders is much slower than transpiling first and passing the JavaScript files directly, so it is recommended that you only do this for development environments.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .