Demystifying JavaScript Build Tooling

Shaping the landscape of available solutions

Raphaël Tahar
5 min readFeb 18, 2023
DALL-E: Tooling landscape

In a previous series post (Part 4: Module resolution & Task runners), we walked through the evolution of the JavaScript module resolution systems over the past decade and briefly mentioned a few task runners. JS modules went from nothing to a fully baked, built-in language feature and task runners evolved into aggregated sets of tools that now do much more than just stitching JavaScript code together.

In this process of continuous improvement and parallel innovations, a whole bunch of tooling has been created in order to ease the use of the wide diversity of tools, formats, and standards available on the market.

Here’s more or less what the chronology looks like:

Building tools and module resolution systems timeline

This graph isn’t exhaustive, or completely accurate. Its purpose is to help depict the parallel between module resolution systems and tooling intertwined evolutions.

First a few words on past glories.

The old-school stuff

There’s one constant, a tool that existed before Christ: Make. I’ve seen quite a few modern projects using it, it does one thing and it does it well. It’s also very useful to homogenize building processes between specialties (ie backend and frontend build flows), especially in environments that use C or C++.

In the same category lives Browserify which, as we saw, allows using the require syntax in a frontend codebase and outputs a bundle injected into an HTML page through a single <script/> tag.

And task runners Grunt, and Broccoli, were heavily used between 2013–14 and 2015–16. Gulp is an exception and is still widely used but mostly on long-lived projects.

The current/next-level stuff

To complete our overall build tools overview with modern tooling (ones that focus on CommonJS and mainly EsModule), the State of JS (2022) will provide us with more accurate and contemporary insights into the present-day tooling landscape.

State of JS: Building tools usage | interest

First things first, let’s talk about the elephant in the room.

In the previous post, we dived into Webpack’s internals because its architecture and features paved the way on so many levels. The above charts show that Webpack is still heavily used.
Between 75 and 85% of respondents since 2017 say they use it.
But folks lose interest in it, in 5 years users claimed that their interest dropped from 84% to 61%.

This is mainly due to the burden of configuration, and performance limitations due to its implementation in JavaScript which is mono-threaded.

To counter this, new tooling provided answers to these 2 issues:

  • multi-threaded language implementation (performance)
  • zero configuration (configuration)

Bundlers/compilers for performance

Performances improvements have been met through next-gen bundlers and compilers. Two languages have been used because of their native abilities to perform multi-threaded computations: Go and Rust.

Go-based bundler: EsBuild

Rust-based bundlers: SWC, Turbopack (alpha)

These tools claim tremendous performance gains.

Esbuild 10–100x faster claim
SWC 20–70x faster claim

But each project is unique and the only way to know to what extent this applies to you is by trying it on your repositories.

Bundlers for zero configuration

Regarding the laborious configuration, tools like Rollup or Parcel came along. The promise: just npm install it, and it’ll do the rest through inference and self-adaptive defaults.

Over the year, Webpack also greatly improved its default settings and reduced the need for engineers to have extended knowledge of its internals in order to use it.

Isn’t there a way to have both performances and zero configuration?

Yes, there is, but at the cost of creating wrapping tools that stitch everything together and cherry-pick the features that are the most interesting.

Parcel (v2) is built on top of SWC so it answers to both the performance gain and the out-of-the-box readiness experience.

Vite is built on top of EsBuild for bundling processes and Rollup for code-splitting and CSS handling.

Turbopack is presented as Webpack’s evolution. Its main maintainers are webpack core team members. It’s also part of a bigger project that proposes to uplift the existing tooling into a Monorepo dimension: Turborepo.

Users’ feedback, feelings, and intents

Finally, the State of JS provides a very insightful vision of which tools are the most engaging in the community.

Users’ distribution: would (not) use / (not) interested

This graph gives pretty good insights into what’s coming up next.

There’s a big chance for you to find either Vite, EsBuild, Turbopack, tsc CLI, or Webpack in your next job (the hype of today is the habits of tomorrow if no disrupter appears during the adoption curve).

Conclusion and opening

All in all, categorizing the JavaScript tooling ecosystem is pretty hard as they all implement different sets of features and are all combined in various ways in order to build applications.

The ecosystem moves fast and tries to break the status quo, in order to bring a better Developer experience and higher productivity through enhanced performances.

This concludes this series on JavaScript’s built-time demystification.

Opening

I intend to write another series focused on the runtime soon.
Stay tuned! :)

The build system is being challenged by the Monorepo philosophy which can be considered as a new vision or as a perception shift.

If you want to know more about it, check out the series I wrote about why and how my chapter decided to adopt it: Monorepo Series.

Thanks for reading!
👏🏻 Give me a clap and “
follow” if you enjoyed this series.

--

--

Raphaël Tahar

Staff Engineer, Chapter Lead and philosophy enthusiast. Proud dog father 🐶. Opinions are my own.