Editor’s note: This post was updated on 14 March 2022 to include information relevant to Snowpack v3 and webpack v5.
So, taking all that into account, and taking the perspective of today’s ecosystem, how do Snowpack and webpack stack up? And, how easy is it to switch from one to the other? This article will attempt to tackle all of that with a detailed comparison of the features and benefits of both tools. We’ll also share a guide for getting started with Snowpack. Let’s get started!
Table of contents
Listen to our podcast episode on Snowpack and webpack here.
For the demo portion of the article, you’ll need the following:
N.B., the modern browser requirement applies only to the development environment. Once you’ve created the final build with Snowpack and pushed it to production, users can view your site in any modern or legacy browser. More details can be found here.
It’s no secret that webpack can be hard to configure, especially for beginners. But it’s also important to remember that webpack is capable of really big, powerful stuff, so it makes sense that some configuration and knowledge is required to use all of that power. Still, even today, there’s no simple command for a “simple” webpack setup, and it still requires a steep learning curve and understanding of what it’s doing for most people.
npx snowpack --include './src/**.js'
Let’s take a look at how to write valid ESM imports:
-import React from 'react'; // 🚫 invalid ESM +import React from '/web_modules/react.js'; // ✅ valid ESM
Although most developers write
react.js, browsers can’t understand it without the file extension because it’s not a valid URL¹. Snowpack allows you to bundle npm packages as single files, so it can generate
react.js with the extensions that browsers can understand. While this may be a change in your codebase, fortunately, it can be as easy as a few find-and-replace commands (for example, replacing
When it comes to alternate syntaxes, too, like
.svelte, Snowpack has some starter projects that can help get you up-and-running there too. Depending on the setup, this could mean either the same level of configuration as webpack, or a little less! But rarely does using Snowpack result in more to manage.
Advantage: 🗻 Snowpack
¹ If you’re thinking “wait… can an ESM import be at any URL? Even a remote one?” then you’re onto something big! ESM can use remote URLs, and we’ll get back to that point in the Using a CDN section below.
When it comes to bundling, Snowpack can help with build handling without requiring a complex config step. With Snowpack, we only have to build each file only once and then the file is cached forever. This means that Snowpack only rebuilds that single file when there is a global change to the files we are watching. This is different from what we are used to from older bundling tools like webpack and Parcel which rebuild all our files when there is a change in just a single file.
In essence, Snowpack supports an “unbundled development” flow in which only the individual files that are changed or updated are shipped out to production, during dev mode. This is all due to ESM import and export syntax. Unlike other build tools, they focus on “bundled development”. This means that every change we make has to be bundled with the unchanged parts of our application before our changes can be reflected in the browser.
Advantage: 🗻 Snowpack
Writing ES module directly for the browser means no wait and an instant preview of your code. Whereas webpack runs on every save, Snowpack only runs when you install a new npm package.
What’s worse: with bundling, the time spent waiting on your code to build scales linearly with the app size. In other words, the larger the app, the longer you wait. But with Snowpack, no matter how big your application code gets, no build time means no build time. While saving milliseconds may not seem like a lot at first glance, over the course of hundreds of times a day, over a few years, that can become hours of your life!
Advantage: 🗻 Snowpack
But there’s an even bigger danger lying in wait with webpack— duplicate code! When you start to split your bundles, if you’re not carefully analyzing all of its contents using webpack-bundle-analyzer, you would most likely have duplicated code. So if a user visits your app, they might not only be downloading a lot of JS — they might be downloading it multiple times!
Snowpack + ES module follows a different strategy. You bundle nothing, instead opting to expose the ESM import tree to the browser. Because the browser understands your app structure, it can then efficiently fetch what it needs directly, and only what it needs. The browser does all of the work and requires zero time commitment from you. Also, it’s impossible to duplicate code or dependencies.
As a result, when using Snowpack + ESM, if you changed your code or an npm dependency a user visiting your site only needs to download the exact files and dependencies that changed and nothing more. If
react’s version changed, the user downloads the new version of
react and everything else it pulled from cache. When it comes to caching, Snowpack really shines—and in this regard, it’s nearly perfect³.
Advantage: 🗻 Snowpack
² webpack’s core proficiency is bundling, so by design, it will try and combine any code and dependencies it can. It’s difficult to configure webpack where one changed file results in only that file being re-downloaded by the user.
³ I say “nearly-perfect” because tree shaking your app code isn’t yet possible with ESM (covered in the Tree Shaking section).
If you read through the Caching section in this post, a question that may have popped up is how do webpack and Snowpack compare in terms of network performance? Loading network assets is one of the most complicated, interesting, and nuanced comparisons between the two tools.
Snowpack’s author, Fred K. Schott, touches on this subject in greater detail in A Future Without Webpack. But to give a crude simplification, Snowpack + ESM exposes the import tree to the browser. That means the browser downloads and scans a
<script> tag, then lists the imports in that file. It then scans those imports, and those imports’ imports, until it reaches the very end of the “tree.” That process of crawling through files will generally result in more network requests than webpack’s bundling. But more files to crawl doesn’t necessarily mean slower.
While reducing your number of requests seems like an open-and-shut case for bundling, and, yes, bundling files will almost always improve download speed for each individual file, the reality is that the situation of modern JS apps has a few more factors to consider than the sum total of network requests. These include:
import()statements you use in your app, the more both Snowpack and webpack will perform identically because the JS fetching is determined by your app, not the tooling
So let’s recap, reducing requests is where webpack shines, but only if your app consists of synchronous
import statements to other modules hosted on your server. The more lazy-loaded code you serve, and the more modules you serve from a remote CDN, the more Snowpack and webpack perform similarly both in number of requests and overall network speed.
Advantage: 📦 webpack but only on initial cacheless load
Arguably the coolest feature of ESM is the ability to use
import statements with remote modules:
import preact from 'https://cdn.pika.dev/preact'; // ┳┻| // ┻┳|_ Psst… // ┳┻|•.•) this is a really // ┳┻|⊂ﾉ big deal // ┻┳|
This is huge! Even though tens of thousands of sites use React, most of them probably hosted their own version rather than using a CDN, which meant as you’ve crawled the web you’ve probably downloaded the same version of React hundreds of times and counting. It’s not the websites’ faults, though—loading
<script> tags for npm dependencies in 2020 is so ancient! It undoes all of the great work that ES module has given us.
But with ESM, you actually can load modules from remote servers—whether that’s a CDN like Pika or even a common CDN you’ve set up yourself.
So Snowpack is the clear winner here, right? Not so fast! While, yes, Snowpack does support remote modules out-of-the-box, a third-party webpack plugin has come about that lets you import external packages from other webpack bundles. However, it is now integrated into the webpack v5 release! Want to check out how to import remote URLs in webpack natively, have a look at the webpack’s official documentation. Hooray, CDN!
Advantage: 👯♂️ both!
Tree shaking, in case you’re unfamiliar with the term, is the process of removing unused code from your app. Say you installed and imported the heavyweight
lodash package into your app, but ended up not using it. That shouldn’t count against you, right? With tree shaking, your app is as small as it can be. webpack is practically the poster child of tree shaking. It is a tree shaking beast and it does it all for you without you having to configure a thing.
But just because Snowpack is an install-time tool doesn’t mean it can’t tree shake! When you run
snowpack--optimize, it can tree shake the dependencies you use. Granted, Snowpack can’t tree shake your app code, but that’s also because it doesn’t touch your app code. If you need tree shaking for your app code, you will have to use a separate tool with Snowpack, powered by Rollup. But a fair assessment is for each tool, both tree shake all the code they manage.
Advantage: 👯♂️ both!
The last comparison that’s worth making is flexibility. When it comes to Snowpack vs webpack, how many different setups, and types of apps can each handle? How much control does each give you over unique setups?
Snowpack is meant to help give you training wheels to writing ESM-ready code for browsers without giving up npm packages and the JS ecosystem. Beyond that, it’s up to you!
If you need to handle code transformation, transpilation, minification, etc. then webpack has just about all the tools you need.
webpack isn’t the only tool—you can use Babel by itself, or Rollup, or any individual thing you need, but when it comes to the “Swiss Army Knife” complete package, webpack is unrivaled. Even though flexibility is a vague and ambiguous term, whatever you need, there’s probably a webpack plugin for that™.
Advantage: 📦 webpack
Perhaps you’ve landed on this article wondering ‘Should I start my project with webpack or Snowpack?’ I’d recommend Snowpack, but only if you can use ESM-ready packages (which you can search for on pika.dev). It’s quick and painless and you can always easily migrate to webpack if needed. But based on your needs, you may find one of the comparisons above at the heart of your project that may tip you in either direction.
Step 1. Install Snowpack
Install Snowpack with npm or yarn using the below installation commands. Note that Snowpack’s creators recommend installing locally, rather than globally, when possible.
id="globalinstallation">global installation npm install -g snowpack local installation per project npm install --save-dev snowpack local installation per project yarn add --dev snowpack
Step 2. Start the Snowpack command-line interface
There are three ways that you can run the Snowpack CLI locally:
Step 3. Initialize the app
To create a new app project, use Create Snowpack App (CSA). With CSA, you get a new initialized app configured using one of Snowpack’s app templates. Snowpack provides templates for React, Vue, Svelte, and other popular frameworks.
Here’s a sample initialization command that uses Snowpack’s template for React:
npx create-snowpack-app new-dir --template \[@snowpack/app-template-react\] [--use-yarn]
You can also find a list of official CSA templates on the Snowpack documentation page.
Step 4. Migrate your existing app to Snowpack
Use the app you created with a CSA template as the starting point for migrating your existing app.
Snowpack supports most of the technologies used for web development nowadays, such as Babel, PostCSS, Create React App, amongst others. Chances are, your app already uses one of these supported technologies, so the migration to Snowpack should be a snap.
In fact, if you have an existing Create React App project, you can run it directly through CSA without making any changes at all.
To migrate an app, begin by initializing a new app project using the CSA template of your choice (see the previous section for instructions). Next, copy over all the files from the
public directories of your existing app site. Now, start your development server and load the site locally using this command:
Now it’s time to troubleshoot any issues you might run into. If you get stuck, check the Snowpack docs for help.
Finally, when you’re ready, build your site for production with:
snowpack build command.
Snowpack lets you work in a lightning-fast, unbundled development environment, and even lets you keep your final builds unbundled and runnable. You also have the option to support bundled builds when it comes time to roll your app out to production. All you have to do is add the right plugin for your favorite bundler, or even write your own using the Snowpack plugin API.
Snowpack offers the following advantages over a traditional bundler tool like webpack:
Let me know in the comments how this comparison stacked up, or if there are any other comparisons you’d like to see!
Leptos is an amazing Rust web frontend framework that makes it easier to build scalable, performant apps with beautiful, declarative UIs.
We spoke with Dom about his approach to balancing innovation with handling tech debt and to learn how he stays current with technology.
Vite is a versatile, fast, lightweight build tool with an exceptional DX. Let’s explore when and why you should adopt Vite in your projects.