loading...
Cover image for A Future Without Webpack
Pika

A Future Without Webpack

fredkschott profile image Fred K. Schott ・6 min read

Note: This piece was originally published to pika.dev.

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, with 15 minutes of airtime 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." [1] It would be a while before anyone would show actual video clips on the TV news.

As a JavaScript developer in 2019, I can relate. We have this new JavaScript module system (ESM) that runs natively on the web. Yet we continue to use bundlers for every single thing that we build. Why?

Over the last several years, JavaScript bundling has morphed from a production-only optimization into a required build step for most web applications. Whether you love this or hate it, it's hard to deny that bundlers have added a ton of new complexity to web development -- a field of development that has always taken pride in its view-source, easy-to-get-started ethos.

@pika/web 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.

Credit: @stylishandy

Why We Bundle

JavaScript bundling is a modern take on an old concept. Back in the day (lol ~6 years ago) it was common to minify and concatenate JavaScript files together in production. This would speed up your site and get around HTTP/1.1's 2+ parallel request bottleneck.

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.

Create React App visualized: 1,300 dependencies to run "Hello World"

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 @pika/web was created.

@pika/web: Web Apps Without the Bundler

GitHub logo pikapkg / web

📦 ✨ Run npm dependencies directly in the browser. No Browserify, Webpack or import maps required. https://www.pika.dev/blog/pika-web-a-future-without-webpack/

Logo

@pika/web • Run npm dependencies directly in the browser. No Browserify, Webpack or import maps required

Logo


npm on Dec 6, 2018 - "JavaScript in 2018 is somewhat notorious for requiring a lot of tooling to get going, which is quite a reversal from the situation in 2014... All of our survey respondents would like to see less tooling [and] less configuration required to get started."


@pika/web brings that nostalgic, 2014 simplicity to 2019 web development:

  • Simple 💪 No bundlers required. Load modern packages natively in the browser.
  • Flexible 🧘‍♂️ Handles dependency trees of any size, even ones that includes legacy Common.js packages.
  • HTTP/2 Optimized ⚡️ No more huge JS bundles. Browsers only download dependencies when they change.

@pika/web installs npm packages as single .js files to a new web_modules/ directory. If your dependency exports an ES "module" entrypoint in its package.json manifest, it is supported. Even if it internally…

@pika/web 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). @pika/web 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 @pika/web
✔ @pika/web installed web-native dependencies. [0.41s]

@pika/web 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. @pika/web works on any ESM package, even ones with ESM & Common.js internal dependencies.

Installed packages run in the browser because @pika/web 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! @pika/web 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 @pika/web 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 @pika/web: Bundle because you want to, not because you need to.

"view-source" is back!

Performance

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 @pika/web, updating a single package won't bust the rest of the user's cache.

@pika/web 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.

To be clear, leaving your application source unbundled isn't all sunshine and roses, either. Large JavaScript files do compress better over the wire than smaller, more granular files. And while multiple smaller files load just as well over HTTP/2, the browser loses time parsing before then making follow-up requests for imports.

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 @pika/web: Add a bundler because it makes sense to your situation, not because you have no other choice.

The Pika Web App Strategy

@pika/web 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:

  1. For new projects, skip the bundler. Write you application using modern ESM syntax and use @pika/web to install npm dependencies that runs natively on the web. No tooling required.
  2. Add tooling as you go. Add TypeScript if you want a type system, add Babel if you want to use experimental JavaScript features, and add Terser if you want JS minification. After 6+ months, pika.dev is still happily at this phase.
  3. 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!
  4. Keep optimizing your bundler config as your application grows.
  5. 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.

Pika

* https://www.pika.dev - npm search for web developers * https://github.com/pikapkg/web - Build better web apps with less tooling. * https://github.com/pikapkg/pack - Create npm packages without the mess.

Discussion

markdown guide
 

I can’t get about got the pika logo 😄

 

Pika looks cool but I have difficulties with understanding how to setup it like Parcel, with live reload, cache etc.

 

Check out our list of examples for how to set up an app or even a PWA: github.com/pikapkg/web/blob/master...

@pika/web is not a server, so you'll need a static file server for local development. Something like npmjs.com/package/serve with live reload configured.

 

thank you for you reply. Things are more clear now. I'll try Pika next time I will make a website / web app

 

Hey !

First, this is a great article.

Bundler should not be required for webdev :)

I really think Compression is a big deal.
Splitting file to file will increase runtime caching but will destroy Gzip or Brotli power.

 

For sure, it all comes down to a balance between the caching improvements that you get, the total downloaded efficiency that you get (no downloading code you don't need), and the compression efficiency of that first download.

One of my favorite things about this strategy is that it's great when you're just starting out and performance isn't your immediate concern. No need to wrestle with a ton of tools just to get a prototype or demo or simple site out there. And then, when you are ready to optimize for production users, you're free to add a bundler to your toolkit if that's what you'd prefer.

 

Great first post. I had heard of pika, but didn't realize how it worked. Looking forward to your next post!

 

Does having "1300 dependencies for Hello World" mean that this will create 1300 dependencies that have to be reloaded with a js file each?

 

Not necessarily, the point was more towards how complex the "starter" Create React App build pipeline. Most of those are Node-only packages specifically for building your app.

 

FYI... react-script is not the npm name of Create React App.

 

I there anyone who has managed to replace webpack/webpacker in a Rails app with pika? If so, please share.

 

Pika works with any server, you would just need to install your web_modules directory to somewhere that Rails would serve it to the browser (app/assets/web_modules?) and then just write your JS imports to point to their final location when served.

We have a few examples here: github.com/pikapkg/web/blob/master...
If you do get it working with Rails, would love if you could add it there!

 

But rollup still needed because pika use that as dependencies 😋

 

Totally! I get to touch on that more in this talk: youtu.be/2Wwx-lF5NhE?t=711

If you don't have time to watch, the tl;dr is that we get to move bundling complexity away from the app (where it's no longer needed) and down to only the dependencies. It's not an attempt to get rid of bundling, but more to refocus it for 2019 on bundling's original purpose:

  1. as a production optimization
  2. as a way to consume npm on the web