Blog
frontend
2 min read

Bundlers Should Be Optimization: Bring Dependency Resolution Back to the Platform

One takeaway: Browsers load ESM by URL. Without a product-grade specifier-to-URL resolution path, bundlers become a practical dependency-resolution layer.

Bundlers Should Be Optimization: Bring Dependency Resolution Back to the Platform

**One-sentence takeaway:** Browsers load ESM by URL. Without a product-grade specifier-to-URL resolution path, bundlers become a practical dependency-resolution layer.

Background / Problem

Browser ESM ultimately resolves every `import` to a URL. But most “package” workflows express dependencies as bare specifiers (package-like names). The larger this gap gets, the more bundlers expand from optimization tools into dependency-resolution layers.

Core Concept

The real chokepoint is “specifier → URL”

Browsers fetch modules by URL. If you write `import "pkg"`, you need a rule that maps that string to a URL the browser can request.

```mermaid

flowchart LR

A["App code<br/>import 'pkg'"] -->|"specifier"| B["Resolution needed<br/>pkg → URL"]

B --> C["Browser ESM loader<br/>fetch(URL)"]

C --> D["Module graph<br/>transitive deps"]

B -->|"Option"| E["Import Map<br/>runtime mapping"]

B -->|"Option"| F["Bundler<br/>build-time resolution"]

```

→ Expected outcome: you can explain “why bundlers show up” in terms of resolution, not performance.

Approach

1) Map specifiers to URLs with an Import Map

  • Why: keep specifiers in code while providing URL resolution for the browser
  • Expected: explicit, runtime-controlled resolution

2) Fix resolution at build time with a bundler

  • Why: handle resolution/transforms/optimization together and simplify runtime URL concerns
  • Expected: specifier-based app code, artifact-based deployment

Implementation

Import Map example

```html

<script type="importmap">

{

"imports": {

"mypkg": "/vendor/mypkg/index.js"

}

}

</script>

<script type="module">

import { hello } from "mypkg";

hello();

</script>

```

→ Expected outcome: the browser rewrites the specifier to a URL per the import map, then expands the module graph from that URL.

Verification Checklist

Import maps are applied before module loading.
Ownership and rollout rules for mapping changes are defined.
Your delivery model accounts for transitive dependencies.

Common Pitfalls / FAQ

**Q1. Does an import map solve everything?**

Import maps provide specifier mapping, but they come with global mapping and timing constraints. At scale, change governance matters.

**Q2. Are bundlers always required?**

It depends on environment and policy. But when the platform doesn’t fully absorb specifier → URL resolution, bundlers tend to become the operational center.

Summary

  • Browser ESM is URL-based.
  • The bottleneck is “specifier → URL” resolution.
  • Import maps and bundlers address that bottleneck at different times (runtime vs build time).

Conclusion

Bundlers should remain an optimization choice. As the platform makes dependency resolution more natural, bundlers move closer to “optional optimization” rather than “mandatory infrastructure.”

References (official docs)

  • [MDN: <script type="importmap">](https://developer.mozilla.org/docs/Web/HTML/Reference/Elements/script/type/importmap)
  • [MDN: JavaScript modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules)
  • [MDN: import](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import)
  • [Next.js Docs](https://nextjs.org/docs)
  • [React Docs](https://react.dev/)
  • [Mermaid Docs](https://mermaid.js.org/)

Related Posts