How to run TypeScript natively in Node.js with TSX
Tags: typescript, node, development, javascript
Published: 2023-11-28 20:07:53

---
title: How to run TypeScript natively in Node.js with TSX
published: true
tags: typescript,nodejs,development,javascript
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/evsqafu69ywkx7gzz12g.png
---

Who hasn't wondered how runtimes like [Deno](https://blog.lsantos.dev/tag/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](https://nodejs.org/api/module.html#transpilation), including using the transpiling example itself.

### TSX

[TSX](https://npm.im/tsx) is the newest and most improved version of our `ts-node`, using [ESBuild](https://esbuild.github.io) 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`:

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

main(5,5)
```

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:

```bash
node --loader tsx index.ts
```

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](https://nodejs.org/en/blog/release/v20.6.0#built-in-env-file-support) 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:

```bash
NODE_OPTIONS='--loader=tsx' node --env-file=.env index.ts
```

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.