Migrating a 150K LOC Codebase to Vite and ESBuild: Why? ({art 1/3)

Stefano Magni
JavaScript in Plain English
4 min readMay 26, 2021

--

What is Vite? Why did we consider it? Is it faster than Webpack? Is it mature enough?

This is part of a three-article series about migrating our React+TypeScript codebase from Webpack to Vite. Part 2 is about how we did it, Part 3 is about post-mortem considerations.

This article is about a React and TypeScript project migrated from Webpack to Vite and ESBuild.

From Webpack’s slowness to Vite

It’s always the same story: you start working on a branch, run yarn start and wait for two minutes. Then you save a file and wait for 20 or 30 seconds before the app gets refreshed. Then you switch multiple times among the branches you’re working on, and you need to relaunch the dev server again. Such a terrible Developer Experience.

We reduced this problem by moving to Vite and ESBuild. Keep on reading.

The WorkWave RouteManager UI team works daily on a 150K LOC (and growing, ~250K LOC is the final size) codebase. Due to the nature of the Product and the technical constraints, there is nothing we can do to split the app into little chunks at the moment. 75% of the code is shared and used by all the app sections.

The app is based on React and TypeScript, spans a Web Worker, uses Webpack, babel-loader, ts-loader, and fork-ts-checker to bundle and validate the code. All the dependencies are updated weekly.

Recently, Vite 2.0 has been released. Its core idea is simple: serving the files “as are” to the browser leveraging ESModules. When the browser parses the source files and asks the web server for an imported file, Vite does

  • convert NPM dependencies to ESModules and serve them
  • transpile your source code through ESBuild
  • serve the code to the browser

What does it mean? It means that Vite doesn’t bundle the code in advance. Instead, when the browser asks for a file, Vite transforms it. A picture is worth more than a thousand words.

The browser performs thousands of requests for the source files (.tsx, .ts), not for the bundled one as happens with Webpack.
The browser loading the thousands of unbundled .ts and .tsx files.

The files are cached, but Vite essentially removes the burden from the build tool, moving it to the browser. You can read more on Vite docs or on CSS-Tricks’ Comparing the New Generation of Build Tools article.

What about the build? Vite leverages Rollup to build the project, no worrying about browser compatibility of the final bundle.

Vite’s advantages

In contrast to Webpack, Vite is not a generic tool. Vite supports a few sweet spots. If your project falls in these spots, Vite offers

  • Better performances, thanks to the speed of ESBuild.
  • Less configuration.
  • Fewer dependencies: everything required for a React+TypeScript project like ours is managed directly by Vite, React Fast Refresh included.

But not all that glitters is gold! What does Vite not include?

  • TypeScript validation: to be short, ESBuild removes type annotations without validating them. You must run tsc on your own to validate types.
  • It depends on your configuration, but in our case, ESLint runs thanks to fork-ts-checker. Vite doesn’t care about ESLint.

Notice: I’m going to talk about these missings in the 3rd part of this series, including some objective considerations about Vite and Webpack and the overall Developer Experience.

Last but not least: are Vite and its ecosystem mature enough?

In the end: betting on Vite is not hazardous. Anyway, we decided to keep the codebase compatible with Webpack to swap between Vite and Webpack in case of trouble.

Benchmarks

To give you an idea of the performance improvements, take a look at our early benchmarks, the ones I shared with the rest of the team

Then, getting the codebase ESBuild-ready allowed us to put Webpack on a diet too, these are our final benchmarks.

Migrating the codebase

The 2nd part of this series deepens the technicalities under the migration of our codebase. The 3rd part is about the conclusions, the DX, and a more fair comparison with Webpack.

Hi, I’m Stefano Magni, I’m a passionate Front-end Engineer, a speaker, and an instructor. I work remotely as a Senior Front-end Engineer / Team Leader for WorkWave.

I love creating high-quality products, testing and automating everything, learning and sharing my knowledge, helping people, speaking at conferences, and facing new challenges.

You can find me on Twitter, GitHub, LinkedIn. You can find all my recent contributions/talks etc. on my GitHub summary.

More content at plainenglish.io

--

--

I’m a passionate, positive-minded Senior Front-end Engineer and Team Leader, a speaker, and an instructor. Working remotely since 2018.