Written by Drew Powers✏️
Snowpack is a next-generation build tool for modern JavaScript applications. It lets you write the latest ESNext JavaScript with no configuration, simpler tooling, and no-wait build times.
So can Snowpack replace webpack? After all, few tools have been as central and important to the JavaScript ecosystem as webpack has. While, yes, Snowpack can replace webpack, both tools came about at different times in JavaScript’s development (webpack in 2012, before ES modules even existed; Snowpack in 2019 when modern browsers support ES Modules and ESNext). So taking all that into account, how do they stack up? And how easy is it to switch from one to the other? This article will attempt to tackle all of that.
Note: before we compare the two, webpack predates Snowpack by several years. webpack has been a cornerstone of modern JavaScript, is a feat of engineering, and the JS ecosystem wouldn’t be what it is today without the ideas webpack brought to the table. The comparisons that follow are purely from the perspective of today’s ecosystem, and don’t undermine the legacy and impact webpack has had on pushing JS forward💛.
Configuration & learning curve
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 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.
By comparison, Snowpack doesn’t need any configuration for most JS apps with itsinclude flag. You simply tell it which of your files to scan for imports like this:
npx snowpack --include './src/**.js'
That’s it! Assuming your JS files are all valid ESNext (i.e. no JSX or special syntax), it will install all of your dependencies in a way you can ship your code straight to production. But on the topic of ES Modules, many might not realize that the imports most of us write don’t closely follow the ES Modules spec:
-import React from 'react'; // 🚫 invalid ESM
+import React from '/web_modules/react.js'; // ✅ valid ESM
Although most of us write react
, not 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 that react.js
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 'react'
with '/web_modules/react.js'
).
When it comes to alternate syntaxes, too, like .jsx
, .vue
, or .svelte
, Snowpack has some starter projects that help get 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.
Build time
webpack is a bundler that transforms your code. Snowpack is an install-time tool that doesn’t do any of that. webpack’s bundling abilities, while impressive, come at a cost, and that means waiting on your JavaScript code every time you hit save (which on large apps can take over a minute to build!😱.
Writing ES Modules directly for the browser means no wait and instant preview of your code. Whereas webpack runs on every save, Snowpack only runs whenever you install a new npm package (which gets rarer over time).
What’s worse: with bundling, your time waiting on your code to build scales linearly with your 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
Caching
Most JavaScript apps these days are 2MB of JS or more (source: HTTPArchive). Making users download & execute that much JS can delay interaction for the user by many seconds. So if that’s unavoidable for the first visit, at the very least users should be saved from this on re-visits.
webpack’s caching story revolves around how you split code, or don’t. Changing a single line of code or a single dependency will cause users to re-download most, or all, of that weight. Your code-splitting setup can minimize that, but in most cases webpack results in repeat users re-downloading more code than what you changed. ²
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 contents using webpack-bundle-analyzer, you’ve likely 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 Modules follow 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. In letting the browser do all this work for you, it required zero time commitment from you and 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 & 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).
Network
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 seemslike 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 app has a few more factors to consider than the sum total of network requests, such as:
- The more async
import()
statements you use in your app, the more both Snowpack & webpack will perform identically because the JS fetching is determined by your app, not the tooling - Also taking into account the Using CDNs section, the more your app takes advantage of CDNs, the more Snowpack & webpack perform similarly
- If using a service worker that aggressively fetches assets, then Snowpack & webpack will also behave similarly as loading behavior is dictated by that
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 & webpack perform similarly both in number of requests and overall network speed.
Advantage: 📦webpack but only on initial cacheless load
Using CDNs
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 Modules have 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. And it’s apparently on its way to become part of the webpack 5 release! As of the writing of this article, webpack 5 isn’t out yet, so it’s unclear what importing remote URLs in webpack looks like. But I’m going to count it as possible for webpack (at least through webpack-external-import before the v5 release).
Hooray, CDN!
Advantage: 👯♂️both!
Tree-shaking
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
in 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. But a fair assessment is for each tool, both tree-shake all the code they manage.
Advantage: 👯♂️both!
Flexibility
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?
While it’s worth mentioning that Snowpack does let you use common setups like JSX + Preact or Svelte, there are two important things to consider when it comes to Snowpack:
- Snowpack requires ESM-ready packages, which means you can only use a small subset of npm packages
- Though it’s been said in this article multiple times already, Snowpack by design won’t touch your app code; that’s for you to configure
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
Conclusion
As stated in the introduction, webpack and Snowpack were introduced to the world seven years apart, with webpack predating it by quite a bit. Both were introduced at different epochs in JavaScript history. Both attempt to solve the prevalent problem at the time. webpack wanted to give JavaScript a module system, integrate with package management, and bundle. Snowpack wanted to de-clutter tooling and let browsers handle JavaScript modules but while keeping npm. And in comparing them, again, it can’t be understated what a milestone achievement webpack was and how foundational webpack was in the history of the web (webpack even has a Wikipedia page—how many open-source projects can say that?).
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.
Let me know in the comments how this comparison stacked up, or if there are any other comparisons you wanted to see!
Plug: LogRocket, a DVR for web apps
LogRocket is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.
In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.
Try it for free.
The post Snowpack vs webpack appeared first on LogRocket Blog.
Top comments (0)