Load Java Script modules with import maps instead of bundlers
Import maps let theme sections share JavaScript modules without bundling. Define a single import map in your layout to deduplicate dependencies across sections and simplify module management. Shopify automatically includes the es-module-shims polyfill for older browsers, so don't load your own copy.
Without import maps, each theme section that uses JavaScript modules has to reference dependencies by full URL or relative path. If multiple sections depend on the same utility module, then each one either bundles its own copy or relies on fragile relative paths. This leads to duplicated code across sections, which increases total JavaScript weight and affects LCP by delaying the main thread.
Import maps solve this by providing a centralized mapping from short names (bare module specifiers) to file URLs. Every section can import from cart-api or utils, and the browser resolves those to the correct asset URLs defined in the map. The module is fetched once, cached once, and shared across all sections.
This also matters for dependency management. When you update a shared module, you change the URL in one place (the import map) rather than updating every section that references it.
Anchor to Define an import map in your layoutDefine an import map in your layout
Place a single <script type="importmap"> block in your theme layout. Use the asset_url filter so Shopify appends cache-busting version parameters.
Anchor to Use bare specifiers in section scriptsUse bare specifiers in section scripts
After you define the import map, any <script type="module"> block in any section can import by name.
Both sections share the same cart-api and utils modules. The browser fetches each module once.
Anchor to Don't load your own ,[object Object]Don't load your own es-module-shims
es-module-shimsShopify automatically includes the es-module-shims polyfill when the browser needs it. Loading your own copy causes duplicate polyfill execution and potential version conflicts:
Anchor to ExamplesExamples
Anchor to Before: Each section bundles its own copyBefore: Each section bundles its own copy
Without import maps, two sections that both need cart functionality either duplicate the code or use script tags with global variables.
The cart logic is downloaded, parsed, and compiled twice.
The cart-api module is fetched and parsed once. Both sections share it.
Anchor to When to use import maps and other approachesWhen to use import maps and other approaches
| Approach | Use when |
|---|---|
| Import maps | Multiple sections share the same modules. You want centralized dependency management without a build step. |
Traditional <script> tags | You have a single small script with no shared dependencies. |
| A bundler, such as Vite or webpack | You need tree-shaking, TypeScript compilation, or complex dependency graphs. The bundler output can still use import maps for shared chunks. |
Because ES modules have their own scope, you don't need to wrap module scripts in IIFEs to prevent variable collisions. The IIFE pattern described in Defer non-critical scripts applies to classic (non-module) scripts only.
Because ES modules have their own scope, you don't need to wrap module scripts in IIFEs to prevent variable collisions. The IIFE pattern described in Defer non-critical scripts applies to classic (non-module) scripts only.
Anchor to TestingTesting
- Open the Network panel in Chrome DevTools and filter by JS. Verify that shared modules, such as
cart-api.js, appear once in the waterfall, not once per section. - Check the Console panel for module resolution errors. A missing entry in the import map causes a
TypeErrorwhen the browser tries to resolve a bare specifier. - View the page source to confirm that Shopify includes the
es-module-shimspolyfill automatically. You shouldn't see a second copy loaded by your theme. - Test in a browser without native import map support (Safari 16.3 or earlier) to verify that the polyfill resolves modules correctly.
- Use the Coverage tab to check whether shared modules contain unused exports that you can split into smaller files.
Anchor to ReferencesReferences
- The Shopify platform: Polyfills
asset_urlfilter- MDN: Import maps
- es-module-shims on GitHub
- MDN: JavaScript modules
- Defer non-critical scripts
- Load JavaScript on user interaction