Testing combinations of build tools and frameworks

With so many options out there, how can you decide which tools are best for your project? By trying out a bunch of them, of course!

Ella Wren
Author
Ella Wren
Published
Dec 22, 2023
Topics
Engineering, Industry

In preparation for the upcoming Recycling Locator rebuild, we wanted to explore which technologies could be used to build the new widget.

Different combinations of frameworks and build tools were used to create a simple version of the landing page. The requirements were:

  • Use a single template with a single CSS file.
  • Use CSS modules with PostCSS.
  • No SSR or a server needed (as the widget is a static build).
  • Keep everything as similar as possible across the different builds.
Design of the new Recycling Locator widget landing page

Design of the new Recycling Locator widget landing page

The build tools tested were:

  • Webpack - a module bundler that has been around for over 10 years.
  • Rollup - introduced in 2014 and similar to Webpack. Has more of a focus on optimising bundling of libraries and packages.
  • Parcel - a zero config bundler from 2017.
  • Vite - a new(ish), opinionated contender using Rollup under the hood.

The frameworks tested were:

  • React - has been used extensively on Etch projects.
  • Preact - similar to React, but optimised for performance and size, although with a smaller community. Can be used either with or without React compatibility.
  • Web components - not really a framework, but a set of web platform APIs for creating custom, reusable, encapsulated HTML tags. Here, this was tested in combination with:
    • Stencil - a compiler for generating web components. Uses Rollup under the hood to bundle components.
    • Lit - a library for building web components. Can be used alongside an additional build tool for production.

Results

When evaluating each of these build tool and frameworks, two key metrics were used to compare each combination. These were:

  • Bundle size - smaller is obviously better
  • Developer experience - a bit woolly, but the general feeling of how I found things like set-up and configuration, overall ease of use, documentation, etc.

Bundle size

The table below shows a breakdown of the bundle size for each framework/build tool combination tested.

FrameworkBuild toolJavaScriptCSS
ReactWebpack1.6 MB
PreactParcel1.48 MB1.89 KB
PreactRollup

3.48 MB; 1.47 MB minified; 1.1 MB gzipped

2.4 KB
PreactVite

1.55 MB; 1.16 MB gzipped

2.04 KB; 0.70 KB gzipped
PreactWebpack

1.48 MB

Web componentsLit + Rollup

19.73 KB; 19.76 KB minified; 6.99 KB gzipped

Web componentsStencil

29.08 KB; 8.53 KB minified; 3.53 KB gzipped

You may notice quite a significant size difference between the web component builds and the others. This seems to be because the two SVGs for the landing page (the Recycling Locator logo and a small illustration graphic) don’t seem to be included in the bundle for the two web component builds. It would have taken too long this time around to figure out how to get this working, so instead I made new builds for each combination without these SVGs included, for ease of comparison.

So after stripping out the SVGs themselves and any packages/code associated with them, it is now much easier to directly compare the bundle sizes:

FrameworkBuild toolJavaScriptCSS
ReactWebpack146 KB
PreactParcel11.52 KB1.89 KB
PreactRollup

71.32 KB; 11.64 KB minified; 4.87 KB gzipped

2.4 KB
PreactVite

12.75 KB; 5.33 KB gzipped

2.04 KB; 0.70 KB gzipped
PreactWebpack

19.1 KB

Web componentsLit + Rollup

19.49 KB; 19.52 KB minified; 6.91 KB gzipped

Web componentsStencil

27.74 KB; 8.12 KB minified; 3.38 KB gzipped

Key takeaways on the bundle sizes:

  • Unsurprisingly, the React (+ Webpack) build is significantly bigger than the others.
  • Comparing the Preact builds with each other, Rollup starts as the largest but becomes the smallest when gzipped.
  • The Vite gzipped build is a similar size to the Rollup build.
  • The Parcel and Webpack Preact builds are both on the larger side.
  • The gzipped web component builds are fairly lightweight - comparable to the smallest Preact builds.

There is however a big caveat that no attempt was made at optimising the bundle size. It’s likely that the builds using more configurable build tools, particularly Webpack, could be optimised much further.

It’s also tricky to compare bundle sizes when the bundles differ so much in their structure, such as whether the CSS is included in the JavaScript file.

Developer experience

Build tools

Webpack and Rollup were both frustrating to use. Although both are clearly powerful, they were difficult to configure and it took a long time to get everything working. Webpack especially had a very steep learning curve. Rollup has lots of plugins available that are supposed to make things simpler, but they seem to be mostly geared towards React. For this test, I found the configurability of both a hindrance rather than a benefit; however, for a real, more complex application (and for someone with more experience and time), I'm sure you could get a lot more out of it.

Vite was easily the best developer experience. The create-preact initialiser for bootstrapping a Vite/Preact application, which included options for setting up Typescript, ESLint etc, worked right out of the box. The plugins for adding functionality were really straightforward to use. As it uses Rollup under the hood, many (although not all) Rollup plugins are compatible. Similarly, PostCSS is built-in and can be configured with plugins.

Parcel sat somewhere in the middle of these. Given that it is a zero-config build tool, I thought it would work straight out of the box like Vite did, but it didn’t quite in this case - I’m not sure why but something about the combination of TypeScript, PostCSS and Preact tripped it up somewhere. The docs were good though.

Frameworks

There’s not much to say about React that hasn’t already been said - we know it well, but it does appear to be unnecessarily heavyweight for this application, and it seems more and more people are moving away from it.

Due to its syntactical similarity with React, Preact felt familiar despite not having used it before. I didn’t dig into it too much for this simple example page but features like Signals look nice. Additionally, having the option for React compatibility could be useful for this application, such as for making use of Mobius, the React-based design system Etch built for WRAP.

The developer experience with both web component builds was also fairly good. In this case, Stencil felt better than Lit, but that may just be because I have used Stencil before whereas Lit was completely new to me. That’s not necessarily a bad thing though - it could make sense to use a tool where there is already knowledge of it within the team.

The docs for Lit were really good on the surface but I still had difficulty setting it up. This may be because it needed an additional build tool to be used alongside it, and I used Rollup (as this is what is recommended in the docs) - maybe an alternative build tool would have been given a better experience? I also didn’t like that any CSS has to be written in the JavaScript, as it meant the CSS linting configuration that worked for all the other builds didn’t work here.

Conclusion

Vite won best build tool in my eyes: the combination of easy initial set-up but the ability to customise the underlying Rollup configuration gives the best of both worlds. It also had one of the smallest bundle sizes out of the four Preact builds.

When it comes to Preact vs web components, I’m less sure. Preact was nice to use given my familiarity with React, but web components potentially feels more future-proof.

My gut feeling is that the best options are Preact + Vite, or web components with… something. There is also the option of some other combination of these tools: for example, Vite also has built in support for Vue.js and Lit, while Preact fully supports web components.