# The bundle is design

> Treat every dependency as a cost the user pays, and know when to use the platform, a few lines of your own, or a library.

Module: How good interfaces think · Level: intermediate · 6 min · https://school.agents.org.in/design/philosophy/the-bundle-is-design

Here are five libraries a typical web app ships, and what each costs a phone before the page can respond. Tap a row to swap the library for what the browser already has built in:

*[Interactive demo: Every library is downloaded by every visitor, on every network. The platform is already there.]*

Swap them all and roughly 145 KB disappears: around three seconds on a slow mobile connection, gone, with nothing lost.

## Every dependency is a tax

A dependency (Code someone else wrote that your project pulls in, usually with npm install. Convenient once, then a cost every visitor pays) is code someone else wrote that your project pulls in, usually with `npm install`. Each one is convenient on the day you add it, and then it is a cost forever: more for every visitor to download, more code that could have a security hole, more updates to keep up with.

All of that ends up in the bundle (The JavaScript files a browser has to download before your page works. Every dependency makes it bigger), the JavaScript file the browser downloads before your page works. **A 5 MB bundle is a design decision, and so is a 50 KB one.** The person on a cheap phone on a train feels the difference before they see a single pixel you designed.

So the bar for adding a dependency should be higher than "it's convenient".

## Use what the browser already has

The web platform has grown a lot. Many libraries that "everyone uses" now have a built-in replacement, a native API (A feature already built into the browser, like fetch, Intl or crypto.randomUUID, so it costs nothing to download), that costs nothing to download.

| Instead of | Use |
|---|---|
| `moment` for dates | `Intl.DateTimeFormat`, `Intl.RelativeTimeFormat` |
| `axios` for requests | `fetch()` |
| most of `lodash` | `Array` methods, `Set`, `Object.fromEntries` |
| `uuid` | `crypto.randomUUID()` |
| `query-string` | `URLSearchParams` |
| jQuery | `querySelector`, `closest`, `matches` |

## Write the five lines

If you only use two functions from a big library, write the two functions.

  **A library for one line (avoid):**

```js
    import uniq from "lodash/uniq";
    const tags = uniq(allTags);
    ```

  **The one line (do this):**

```js
    const tags = [...new Set(allTags)];
    ```

## Draw simple shapes in CSS

The same goes for images. A dot, a ring or a chevron does not need a file to download.

```css
.dot { width: 8px; height: 8px; border-radius: 50%; background: var(--accent); }
.chevron {
  width: 8px; height: 8px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
}
```

No request, no image to decode, no alt text to maintain. The shape lives in the stylesheet.

## When a library is the right call

This is not "never install anything". Some things are genuinely worth it:

  **Step: Hard to get right.** Cryptography, a framework like React, tricky date parsing. Writing your own is how bugs get in.

  **Step: Security-maintained.** Payment and sign-in clients, where a dedicated team watches for problems.

  **Step: Small and focused.** A tiny package with one clear job, like `clsx` for joining class names.

  **Step: Speed matters more right now.** A prototype or an internal tool can grab whatever is fastest. Calibrate to how long the code will live and who will load it.

*("It's convenient" is not on that list.)*

Agents reach for packages by reflex, because most code they have read imports them. So ask the question for them:

**Before you install (paste into your agent):**

```text
Before adding any new dependency, tell me its gzipped size and whether the browser or a few lines of our own code can do the same job. Only install it if it is hard to get right, security-maintained or tiny and focused, and say which.
```

**Audit the bundle (paste into your agent):**

```text
List our dependencies with their approximate gzipped sizes. For each one, say whether a native browser API or a short utility could replace it (Intl for moment, fetch for axios, crypto.randomUUID for uuid, Array and Set for lodash). Don't change anything yet; give me a table.
```

**Check yourself:** Your agent wants to install moment to format one date on a page. What is the better first move?

- [ ] Install moment; it is the standard
- [x] Use Intl.DateTimeFormat, which is built into the browser
- [ ] Install moment and lodash together
- [ ] Format the date on the server with jQuery

*Why:* Intl.DateTimeFormat formats dates natively at zero download cost. moment adds tens of kilobytes every visitor pays for.

## In the skill

- https://school.agents.org.in/skill/philosophy/dependency-discipline.md
