TypeScript Benchmark: Bun vs Deno vs esbuild+node vs ts-node

CP Lepage
JavaScript in Plain English
4 min readAug 3, 2023

--

It’s been a couple of months now since bun and deno have been evolving in the space, and I’ve been contemplating whether I should make any changes to my current toolset. I’m a huge fan of esbuild for it’s incredible speed, but sometimes setting it up can be a bit hazardous. Therefore, I’m wondering if I should just use ts-node or maybe get into the built-in typescript runtimes that bun and deno offer. Let’s try to answer my questionings with what programmers love the most: benchmarks.

I’ve setup a little benchmarking tool to test the TypeScript execution of a fibonacci script. For bun, deno and ts-node, the script is launch directly from a single command, but for esbuild+node I’ve made a little two commands snippet like this

esbuild fibonacci.ts --outfile=fibonacci.js; node fibonnaci.js 10

This way, it takes into account the time spent by esbuild to transpile our script before the execution.

Everything has been tested inside FullStacked Cloud. A remote dev environment where node, bun and deno can run without having to install anything on your machine! Check it out https://fullstacked.cloud

I ran every script 50 times and calculated the average for each setup. I also ran the output js with node alone to see the impact of the transpilation in ts-node and esbuild.

Up to here, everything stays the same. There is not enough load to really see the computation impact on each different runtimes. But we can confirm that:

  • Bun is definitely the fastest
  • Deno is second
  • The difference between node alone (running the js output) and esbuild+node (aka the time for esbuild transpilation) is ~10ms
  • We can already realize how much time we lost with ts-node
  • Now it’s getting interesting, node is almost executing at the same time as deno. But there is that extra 10ms if we include the esbuild transpilation for a real TypeScript execution.
  • Here we reached the point where esbuild+node is equal to deno, which mean that at that load of computation, switching from a node+esbuild setup to deno, might not make any performance differences.
  • Bun is still far ahead in every way.
  • ts-node is still far behind
  • Finally esbuild+node is a bit faster than deno.

Conclusions

  1. Nobody should use ts-node as is. Maybe it can be faster with some extra loader or custom stuff around it?
  2. A good esbuild+node setup is still relevant. It gets faster than deno at some point, but who actually uses this much computation in a JS app? So just like they advertise themselves, for anything where cold start is important like serverless stuff, deno should prevail node+esbuild.
  3. Bun is definitely the fastest. Although, it also feels like the closest one to the bleeding edge. I guess your choice between deno and bun will stand on how willing you are to live with unexpected changes and having to adapt some of your stuff.

If you are like me and you live for those autocompletions in a well-organized TypeScript project, I think it’s time to consider the new kids on the block. With npm support in all three runtimes, a world where you can seamlessly swap from one to another might not be too far off, and each of the runtimes will have its own use case niche.

Here the version of each tool used

$ bun --version
0.7.1

$ deno --version
deno 1.35.3 (release, x86_64-unknown-linux-gnu)
v8 11.6.189.12
typescript 5.1.6

$ esbuild --version
0.18.17

$ ts-node --version
v10.9.1

$ node --version
v18.17.0

and the code used for the benchmarks: https://github.com/cplepage/bench-ts-node-bun-deno

In Plain English

Thank you for being a part of our community! Before you go:

--

--

I’m a web developer and I’m here to write about stuff I work on. Simply putting into word my thoughts and trying to make sense out of it.