Modulepreload for JavaScript ES Modules

Use modulepreload to preload ES modules with dependency resolution. Learn how modulepreload differs from regular script preload and when to use it.

Preload Use Cases

Detailed Explanation

Modulepreload for ES Modules

<link rel="modulepreload"> is a specialized resource hint designed specifically for JavaScript ES modules. It goes beyond regular preloading by also parsing the module and resolving its static dependencies.

modulepreload vs preload for Scripts

<!-- Regular preload: fetches only, does not parse -->
<link rel="preload" href="/js/app.js" as="script" />

<!-- Modulepreload: fetches, parses, AND resolves dependencies -->
<link rel="modulepreload" href="/js/app.mjs" />
Feature preload as="script" modulepreload
Fetches the resource Yes Yes
Parses the resource No Yes
Resolves static imports No Yes
Works with type="module" Partially Fully
Connection sharing No guarantee Guaranteed

How Module Dependency Resolution Works

When the browser encounters modulepreload, it:

  1. Fetches the specified module
  2. Parses the module source code
  3. Discovers static import statements in the module
  4. Fetches those imported modules as well
  5. Stores everything in the module map ready for instant execution
// app.mjs
import { initRouter } from './router.mjs';
import { setupStore } from './store.mjs';
import { renderApp } from './render.mjs';
<!-- Modulepreload also fetches router.mjs, store.mjs, render.mjs -->
<link rel="modulepreload" href="/js/app.mjs" />

When to Use modulepreload

  • Entry point modules — your main application module that imports other modules
  • Route-specific modules — modules loaded when the user navigates to a specific section
  • Web workers — worker scripts that use ES module syntax

Limitations

  • Does not resolve dynamic imports (import()) — only static import statements
  • Browser support is growing but not universal — check caniuse.com
  • The as attribute is implicitly "script" and should not be set to anything else

Example with Multiple Modules

<link rel="modulepreload" href="/js/app.mjs" />
<link rel="modulepreload" href="/js/vendor.mjs" />

<script type="module" src="/js/app.mjs"></script>

Preloading the vendor module separately ensures it starts downloading in parallel with the app module rather than waiting for the app module to be parsed first.

Use Case

A single-page application built with vanilla ES modules uses modulepreload for its entry point module. Without modulepreload, the browser discovers dependencies in a waterfall pattern (fetch app.mjs -> parse -> fetch router.mjs -> parse -> fetch store.mjs). With modulepreload, all modules are fetched in parallel, reducing JavaScript initialization time by 40%.

Try It — Preload Generator

Open full tool