The goal

As the codebase kept on growing, we started running into problems with poor developer experience, slow build times, failing hot module replacement and more. Our Webpack config was also a bit of a nightmare to maintain.
However, there’s no point in swapping stuff out just for the sake of doing it. So before starting the move, we had to define a few goals that should stay top of mind when doing our research. A few things were particularly important for us in this move:

  • Fast build times
  • Performant bundle
  • Great developer experience
  • Maintainable config

Let’s have a quick look at each of these goals in turn, and see how Vite was able to help us in achieving this.

Fast build times

Vite uses esbuild, an extremely fast JavaScript bundler, to achieve tremendous dev server speeds. However, it does not use it to bundle the application. The rationale behind this is explained here. Esbuild has some ways to go when it comes to bundling. That is why, for the time being, Vite is using Rollup.

Our webpack setup used esbuild-loader to make sure that our build times were fast. When moving to Vite, we didn’t experience a great improvement in build times, but fast enough. We are seeing similar build times for our repo with Webpack and Vite.

Performant bundle

Our JavaScript bundle with Webpack was very bloated. We wanted to support older browsers, and doing all that with one bundle makes it all less performant, and also slower to build. With Vite, you can build one modern bundle for modern browsers, and a legacy bundle for older browsers. That’s a very nice way of gaining performance on modern browsers by doing very little. It was quite mind boggling to see how vastly it improved our load times.

Great developer experience

We have quite a few frontend developers at Kahoot!, and for the most part, we work in the same repo. To make sure that everyone is as effective as possible, we’d like the developer experience to be frictionless, and not get in the way of us being able to solve our tasks quickly. With the Webpack setup, this all took a great blow when HMR stopped working. Imagine being in the middle of a Kahoot! session, you tweak some code for a small component and the entire page reloads. A very poor developer experience. With Vite, those problems are a thing of the past. We now have super quick HMR, and the development server starts in no time thanks to esbuild, and Vite using ESModules.

To give you an idea of how development server startup time improved with Vite, you can have a look at the table below:

Webpack Vite
Project 1 ~30s 1.8s
Project 2 ~12s 1.4s
Project 3 ~20s 1.5s

Vite is actually consistently launching the dev server in under 1 second for all our projects. The reason it’s a bit slower in the table above is because we fetch a token that’s automatically injected so that we don’t have to authenticate all the time.

Maintainable config

I don’t think anyone at Kahoot! was fully familiar with the Webpack config. The repo was originally created using create-react-app, and ejected to gain control over config. Over the years, this config was changed slightly to account for some of our needs. As the codebase grew, this only got worse, and the move to Vite was very welcome.

Vite is opinionated. It comes with very sensible defaults out of the box. That being said it is also extensible to the point where you can customize nearly everything. The overall experience of setting up Vite was very simple compared to Webpack. The fact that our codebase is approximately 4 years old means that not everything works out of the box, but it requires minimal tinkering to get it working. We were able to remove quite a few unnecessary scripts, vastly simplifying the overall config.

To sum things up, we strongly encourage you to have a look at Vite. It’s a tool we’ve grown to love very fast. It’s a modern approach to an old problem. The future of frontend tooling is looking very bright.