3 libraries for how to best setup Typescript compilation with Javascript rerendering

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 and node-dev

Cons

  • Does not support NODE_OPTION flag(s), which means we have to exit ts-node-dev to run nodewith 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 🙂