Bundler

Tool

A tool that reads how scattered front-end files depend on each other and combines them into a few packages a browser can download efficiently.

Why it exists

Early web pages announced their files to the browser one at a time. A line at the bottom of the document named a script, the browser read the lines in order, and it fetched each file as it went. With five files, nothing about this was a problem.

Pages grew, sixty of those lines piled up, and ordering became the thing that hurt. A file near the bottom used a value created by a file near the top, so moving one line by a single position turned the screen white. Name collisions were frequent too: when two files used the same name, whichever loaded later overwrote the earlier one, and nobody found out who had overwritten whom until something broke. A new hire would move one line, break the page, and ask why.

Speed was the other problem. Each file meant a separate round trip to the server, so sixty files meant sixty round trips. Files small enough to read in a blink were spending more time in transit than in use.

A bundler hands that work to a machine. Each file declares what it needs, the bundler reads those declarations, works out the order on its own, and gathers what's actually required into a handful of packages. Removing the human from the ordering problem is the largest thing this tool changed. Teams had been solving it by hand before that, keeping a script that pasted the files together in a fixed sequence, and that script became its own thing to maintain every time a file was added or renamed.

What it solves

A bundler addresses four problems. They look like separate jobs, but all four fall out of the same pass over the code.

  1. Resolving dependencies. It walks the files, records which one needs which, draws that into a graph, and derives the order from the graph. Nobody maintains a list of script tags anymore.
  2. Cutting request counts. Twelve hundred files collapsed into three or four packages means that many fewer round trips. The saving shows up plainly in how long the first screen takes, and it grows on slow mobile connections, where the fixed cost of opening each connection dominates the cost of the bytes themselves.
  3. Translating what browsers don't read. Browsers understand JavaScript and not TypeScript or anything else layered on top, so the bundler converts it into a form they do understand. Importing stylesheets or images from code goes through the same step.
  4. Shrinking the output. Whitespace and comments come out, variable names get shortened, and adding tree shaking — which drops code nothing actually calls — can take a 2.4 MB output down to 380 KB.

Packages don't have to be single. Code used on every screen stays in one package while code used on a single screen gets separated out, which is code splitting. The separated package downloads when someone opens that screen rather than at first load.

Package filenames carry a string derived from their contents. Identical contents produce an identical name, so the browser reuses what it already downloaded; change one character and the name changes and the file comes down fresh. That's what keeps every deployment from forcing every user to re-download everything.

Alternatives

There are three alternatives, though none of them removes the bundler so much as uses it less or hides it.

  1. Letting the browser read modules directly. Current browsers can follow dependencies between files themselves, so unbundled code will render. That's comfortable during development, but shipping it to production produces a chain where one file requests another that requests another, and the round trips on the way to the first screen go up rather than down.
  2. Skipping the bundle in development and building one only for production. While someone is editing a screen, the dev server transforms and returns only the file the browser asked for; the full bundle happens at release time. Recent tools default to this, and it shortens the gap between saving a change and seeing it.
  3. Pulling libraries straight from a CDN. A CDN serves assets from a location near the user, so a common library fetched from one never enters your own output. In exchange you can't pin the version yourself, and if that service goes down your screen goes with it.

The most common choice in practice is none of the three. A framework carries a bundler inside it and the people using it never open a config file. The bundling still happens exactly as before. The moment output size becomes a problem, someone ends up looking underneath anyway.

How it sounds at work

"The bundle size is up to 1.8 MB. Is anyone watching what's getting pulled in?"

The output grew and the first screen got slower, so it's time to find what was added.

"Don't import the whole library — import the function you're using."

A note that how you import decides whether unused code rides along into the output.

"Did someone touch the bundler config? The build went from three minutes to nine."

Changing the bundling rules moves build time directly.

At Pagedeck this came up during a conversation about first-screen speed. Noa added a font preview to the document editor and imported an entire typography library to do it, and the next deployment took the output from 900 KB to 1.8 MB.

Theo opened the composition report the bundler produces and pointed at the package that had grown. Two changes fixed it. The import was narrowed to the two functions actually in use, and the preview screen's code was split out so it downloads only when someone opens that screen. The output came back down to 1.0 MB.

What people get wrong

The most common mistake is thinking a bundler makes code run faster. The output gets smaller and the screen appears sooner, so it looks that way. What shrank, though, is the time spent fetching the code, not the time spent executing it. A screen that freezes while rendering ten thousand rows at once freezes exactly as long with the bundle cut in half. Confusing the two costs days of looking for slowness in the wrong place.

Assuming bigger single packages are better is common too. Since the goal was fewer requests, combining everything sounds right. But one package means the first screen downloads code it has no use for — admin-screen code arriving at the login screen. It also means a one-line change renames the whole package, and every user downloads all of it again. The workable middle is a few packages split along how often the code changes and how many screens need it.

Where to go next

  • Frontend

    see where this tool sits among the stages of front-end work

  • Tree shaking

    the standard way to shrink the output while bundling it

Last updated 2026-09-16