Update (03-29-2020): This article was originally written about a year ago about a new project called
@pika/web. Early this year that project was superseded by Snowpack, a web application builder for less tooling and 10x faster iteration. This article has been updated all references from
The year is 1941. Your name is Richard Hubbell. You work at an experimental New York television studio owned by CBS. You are about to give one of the world's first major TV news broadcasts, and you have 15 minutes to fill. What do you do?
In a world that has only known radio, you stick to what you know. That is, you read the news. "Most of the [televised] newscasts featured Hubbell reading a script with only occasional cutaways to a map or still photograph."  It would be a while before anyone would show actual video clips on the TV news.
Snowpack is an attempt to free web development from the bundler requirement. In 2019, you should use a bundler because you want to, not because you need to.
Why We Bundle #
How did this nice-to-have optimization become an absolute dev requirement? Well, that's the craziest part: Most web developers never specifically asked for bundling. Instead, we got bundling as a side-effect of something else, something that we wanted realllllllly badly: npm.
npm -- which at the time stood for "Node.js Package Manager" -- was on its way to becoming the largest code registry ever created. Frontend developers wanted in on the action. The only problem was that its Node.js-flavored module system (Common.js or CJS) wouldn't run on the web without bundling. So Browserify, Webpack, and the modern web bundler were all born.
Complexity Stockholm Syndrome #
Today, it's nearly impossible to build for the web without using a bundler like Webpack. Hopefully, you use something like Create React App (CRA) to get started quickly, but even this will install a complex, 200.9MB
node_modules/ directory of 1,300+ different dependencies just to run "Hello World!"
Like Richard Hubbell, we are all so steeped in this world of bundlers that it's easy to miss how things could be different. We have these great, modern ESM dependencies now (almost 50,000 on npm!). What's stopping us from running them directly on the web?
Well, a few things. 😕 It's easy enough to write web-native ESM code yourself, and it is true that some npm packages without dependencies can run directly on the web. Unfortunately, most will still fail to run. This can be due to either legacy dependencies of the package itself or the special way in which npm packages import dependencies by name.
This is why Snowpack was created.
Snowpack: Web Apps Without the Bundler #
Snowpack installs modern npm dependencies in a way that lets them run natively in the browser, even if they have dependencies themselves. That's it. It's not a build tool and it's not a bundler (in the traditional sense, anyway). Snowpack is a dependency install-time tool that lets you dramatically reduce the need for other tooling and even skip Webpack or Parcel entirely.
npm install && npx Snowpack ✔ Snowpack installed web-native dependencies. [0.41s]
Snowpack checks your
package.json manifest for any
"dependencies" that export a valid ESM "module" entry point, and then installs them to a local
web_modules/ directory. Snowpack works on any ESM package, even ones with ESM & Common.js internal dependencies.
Installed packages run in the browser because Snowpack bundles each package into a single, web-ready ESM
.js file. For example: The entire "preact" package is installed to
web_modules/preact.js. This takes care of anything bad that the package may be doing internally, while preserving the original package interface.
"Ah ha!" you might say. "That just hides bundling in a different place!"
Exactly! Snowpack leverages bundling internally to output web-native npm dependencies, which was the main reason that many of us started using bundlers in the first place!
With Snowpack all the complexity of the bundler is internalized in a single install-time tool. You never need to touch another line of bundler configuration if you don't want to. But of course, you can continue to use whatever other tools you like: Beef up your dev experience (Babel, TypeScript) or optimize how you ship in production (Webpack, Rollup).
This is the entire point of Snowpack: Bundle because you want to, not because you need to.
Installing each dependency this way (as a single JS file) gets you one big performance boost over most bundler setups: dependency caching. When you bundle all of your dependencies together into a single large
vendor.js file, updating one dependency can force your users to re-download the entire bundle. Instead, with Snowpack, updating a single package won't bust the rest of the user's cache.
Snowpack saves you from this entire class of performance footguns introduced by bundlers. Duplicated code across bundles, slow first page load due to unused/unrelated code, gotchas and bugs across upgrades to Webpack's ecosystem... Entire articles and tools are devoted to solving these issues.
It all comes down to a tradeoff between performance, caching efficiency, and how much complexity you feel comfortable with. And again, this is the entire point of Snowpack: Add a bundler because it makes sense to your situation, not because you have no other choice.
The Snowpack App Strategy #
Snowpack has completely changed our approach to web development. Here is the process we used to build pika.dev, and how we recommend you build your next web application in 2019:
- For new projects, skip the bundler. Write you application using modern ESM syntax and use Snowpack to install npm dependencies that runs natively on the web. No tooling required.
- When you feel the need & have the time, experiment by adding a simple bundler for your application source code. Performance test it. Is it faster on first page load? Second page load? If so, ship it!
- Keep optimizing your bundler config as your application grows.
- When you have enough money, hire a Webpack expert. Congratulations! If you have the resources to hire a Webpack expert you have officially made it.