At Prosopo, we're using TypeScript to build Procaptcha, as it offers static type checking and improved code quality. However, running TypeScript requires a transpiler to convert TypeScript code to JavaScript. One of the most popular tools for this task is ts-node, which compiles TypeScript files on-the-fly and executes them directly in Node.js. This is very useful, but there are a couple of problems with ts-node that we will explore in this article.

Problems with ts-node

1. Performance Overhead

ts-node compiles TypeScript files on-the-fly, which can introduce a significant performance overhead compared to precompiled JavaScript files. Each time a TypeScript file is executed, ts-node must transpile the code to JavaScript before running it in Node.js. This compilation step can slow down the startup time of your application, especially for larger codebases.

2. Poor User Experience

This is a strange one. You would imagine that ts-node would be able to run TypeScript files out of the box. However, a simple script that logs something to the console will fail. Our script.ts contains the following code:

console.log('In a TS File!')

When you try to execute this script from the command line, you get the following rather perplexing error:

> node --version
v20.12.2

> ts-node --version
v10.9.2

> ts-node script.ts
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for /home/user/dev/script.ts

OK, let's try the --esm flag:

> ts-node --esm script.ts
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for /home/user/dev/script.ts

OK, let's try switching the node version:

> nvm use 18
Now using node v18.18.2 (npm v10.5.2)

> ts-node script.ts
zsh: command not found: ts-node

> npm i -g [email protected]
added 20 packages in 3s

> ts-node --version
v10.9.2

> ts-node script.ts
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts"

OK, time to try something else, it's sunny outside and we're getting nowhere. ☀️

Alternatives to ts-node 🌅️

Slow load times and unexpected errors are a couple of the problems we face when using ts-node. Here are some alternative approaches.

1. Precompiling TypeScript with tsc

One of the most straightforward alternatives to ts-node is precompiling TypeScript files with the TypeScript compiler (tsc). By running tsc to compile TypeScript files to JavaScript before executing them in Node.js, you benefit from static type checking, improved performance, and better debugging support. It takes slightly longer to test your code but its a more robust solution.

In the above example we would run the following commands:

> tsc script.ts
> node script.js
In a TS File!

However, its worth noting that more complex setups will require a tsconfig.json file to configure TypeScript.

2. Using tsx

tsx compiles TypeScript files on-the-fly, similar to ts-node, but with a much faster startup time because its using esbuild under the hood. Esbuild is written in Go, whereas most JavaScript build tools are written in JavaScript. Javascript is an interpreted language, which means it will never match a compiled language like Go in terms of computation and raw performance. Go was made by Google and designed for high performance.

> tsx --version
tsx v4.15.7
node v18.18.2

> tsx script.ts
In a TS File!

Our tiny file instantly runs, with no load time, and no tsconfig.json required. Hooray!

Limitations of tsx

Fast load times and easy CLIs are great but there are some limitations to be aware of.

From the tsx site:

TypeScript & ESM transformations are handled by esbuild, so it shares some of the same limitations such as: Compatibility with eval() is not preserved Only certain tsconfig.json properties are supported emitDecoratorMetadata is not supported For details, see esbuild's JavaScript caveats and TypeScript caveats documentation.

Conclusion

ts-node is an enduringly popular tool for running TypeScript on-the-fly. However, it has some serious limitations in terms of user experience. If you want to run a simple script, and not wait ages for it to load, tsx is a great replacement. However, when it comes to build time, stick to tsc to ensure that your types are checked and your code is safe. All in all, with the alternatives that exist today, we think it's time to drop ts-node!

DISCLAIMER

No ts-nodes were harmed in the making of this article. 😇

Ready to ditch Google reCAPTCHA?
Start for free today. No credit card required.