This post was updated in May 2024, to include a new contender with fewer tools as a potential winner as my personal preference.
For Javascript, we are lucky to have an extremely popular library titled nodemon
. For Typescript, we’re not quite as lucky. But we do have a few options!
In this short article, I’ll try to elaborate on some of those choices as well as my experience working with some of them.
There’s a few simple requirements that we need met for our ideal solution:
- Typescript compiles every time we save a
.ts
file in our project - Based on the typescript compilation our javascript automatically re-renders, so we have the latest code available to us, without having to restart a server or rerun
node dist/index.js
(or something similar).
So let’s get cracking!
First up, tsc –watch
Using typescript we automatically get this option automatically, no need to install anything extra. In the same manner we can manually compile our ts code on demand using tsc
we can tell it to watch our files using tsc --watch
.
This reads the configuration provided by our tsconfig.json
file and makes it easy to use, as we don’t need to supply anything extra. Easy!
Unfortunately, this method also has a few drawbacks.
The biggest one for me, is that it doesn’t automatically re-render the javascript server. So if I want to have something that listens on my Javascript files and reloads them on updates, still need to add on something like nodemon
.
Pros
- Ships with Typescript, so available out of the box
- Easy configuration implied from
tsconfig.json
Cons
- Doesn’t automatically re-render Javascript and therefore requires manual reload of JS files (eg.
node dist/index.js
).
In the end, this didn’t end up working for me, as the one con it has is a big one for me.
Moving on..
Let’s try ts-node
Our second contender today is called ts-node
. This library seems to be offering a solution to my one issue, in that it renders javascript! Nice!
Let’s take a look.
ts-node
is easy to setup and only required me to install one extra library, assuming of course you have typescript
installed locally in your project.
You simply input the primary command the library offer – sharing the same name as the library itself – followed by the name of the file you wish to execute (let’s use index.ts as our example):
ts-node index.ts
And voilá!
We now get the desired compilation and whenever we make an update to index.ts
, or any of the linked files in our project, yay!
It simply calls tsc
and node
under the hood and collapses two simple steps into one for you.
Ready to call it a day?
… Well, unfortunately, I’m not!
As it turns out, ts-node
is quite ineffective and as such takes a long time to compile and re-render. This gets incredibly annoying faster than it should, and I was already seeing compilations taking 10-15, sometimes 30 seconds at a mid-sized project that was only halfway through its conversion from js to ts.
That won’t work for me, so let’s keep looking. But first, let’s sum up.
Pros
- Handles both ts compilation and js rendering
- Fast to get going, as it supports
tsconfig.json
and gets its configuration from there. - Supports
NODE_OPTIONS
flag(s), which can be helpful for debugging.
Cons
- Is an extra library you have to install
- Slow compilation
So let’s keep looking!
Lastly, ts-node-dev
Our final entry of the day, ts-node-dev
is by far my favorite library for typescript compilation.
This library borrows a bit from ts-node
and specifically tries to deal with the issue of slow compilation that it faces.
It also supports passthrough configuration from both ts-node
and node-dev
(which ts-node
is also built upon).
ts-node-dev
has, in my experience, been by far the fastest compilation experience, and the more optimized we have made our codebase, the better it has gotten.
Recently we started paying attention to updating all of our dependencies and we are down to a consistent ~2second compilation and re-render after successfully converting all our javascript to typescript.
In other words, it beats ts-node
by dimensions.
Another benefit is that we have seen an enormous reduction in the amount of memory/heap overflow issues we have had, but perhaps that is just a consequence of the general typescript optimizations we’ve made over time.
Pros
- Fast compilation!
- Handles both ts compilation and js re-rendering
- Easy to configure and relies on
tsconfig.json
as well as extra configuration, specific to the library - Supports passthrough configuration from
ts-node
andnode-dev
Cons
- Does not support
NODE_OPTION
flag(s), which means we have to exitts-node-dev
to runnode
with the flag(s) we need. - Is an extra library on top of
typescript
that we have to install and manage
Update – a 2024 contender with pnpm
Matt Pocock recently presented his way of serving a node app in a blog post. Naturally I was tempted to try it and went ahead immediately. Since I already had pnpm
installed, it was an easy setup to try this out, and surprisingly it just works.
I particularly like the idea of setting up two separate scripts, that would normally require third party libraries, but in this case didn’t need them.
The less tooling I have to use, the happier I generally am. It’s like that old adage; the best code is the code that was never written.
I opted to try it in favor of my previous favorite ts-node-dev
and noticed it was easily outperforming the previous way of doing things.
One thing I found a tiny drawback, is that using pnpm
to run both the dev:
scripts in parallel caused a relatively small terminal output, one that is too tiny for the needs of this particular project.
However, I’m sure this is something that can be fine-tuned for getting the optimal configuration.
Conclusion: Best library for typescript compilation
All in all, I would definitely recommend trying all of these out and see if you get the same results! If you do, I’m always curious to learn and hear other experiences with libraries.
If you’re just curious about becoming a better Typescript developer in general, why not sign up for my newsletter and get tips and tricks directly in your inbox?
I mail about once a week and promise I won’t spam you 🙂