Optimize bundle size
UI extensions on API version 2025-10+ run on Remote DOM, which limits an extension's JavaScript bundle to 64 KB (compressed). Full-page customer account extensions have a 128 KB limit because they can support end-to-end account-management workflows. The device that renders your extension downloads, parses, and runs that bundle first, so a smaller bundle means your extension appears sooner. The limit is enforced per extension at deploy.
This guide applies to checkout, customer account, admin, and POS UI extensions.
Anchor to Measure firstMeasure first
When you run shopify app build with Shopify CLI version 3.92.0 or higher, it emits an esbuild metafile (.metafile.json) in each extension's dist/ folder. The metafile lists every module in your bundle and how much each one contributes.
To visualize the metafile, upload it to the esbuild bundle analyzer or use a local analysis tool that supports the esbuild metafile format. Start with the modules that contribute the most, and regenerate the metafile after each change to measure the impact.
Anchor to Replace heavy librariesReplace heavy libraries
Prefer a platform primitive or browser built-in over a dependency. When you do need a library, choose a small, tree-shakeable one and import only what you use.
Common swaps:
| Instead of | Use |
|---|---|
react / react-dom | preact, the Remote DOM runtime |
moment | dayjs, or date-fns with per-function imports |
lodash (full import) | the specific functions you need |
axios | the built-in fetch |
crypto-js | the Web Crypto API |
Apollo Client | the platform data APIs, or a plain fetch |
Anchor to Move data out of the bundleMove data out of the bundle
Anything that isn't executable code usually belongs outside the bundle.
- App data: store it in metafields or metaobjects and read it at runtime, instead of embedding large object or array literals.
- Translations: deliver them through the native localization APIs for your surface: checkout, customer accounts, admin, or POS.
- Images: consider hosting larger images and referencing them by URL instead of inlining them. A few tiny inline icons are fine, but dozens of them, or any sizable asset, add up quickly.
Anchor to Remove duplicate dependenciesRemove duplicate dependencies
If two dependencies pull in the same library at different versions, both copies ship. Align the declared versions so it's bundled once.
Anchor to Ship only the code you useShip only the code you use
- Import specific functions, and keep dependencies tree-shakeable (ESM) so the bundler drops what you don't call.
- Prune reachable but unused code: dead imports, side-effectful modules, and non-tree-shakeable dependencies. (Genuinely unreachable modules are already dropped.)
Anchor to Structure your extensionsStructure your extensions
When you design and build a new extension, how you split functionality decides what each device downloads.
- One feature per extension: Separate capabilities a merchant enables independently, so only the code behind what they turned on gets loaded.
- Don't combine targets that never render together: A checkout block bundled with an Order status widget, or an admin block for one resource page bundled with an action for another, forces every render to download code that can't run there.
- A full-page customer account target stands alone: A full-page target can't be combined with any other target in the same extension, so a full-page extension always has its own bundle and the 128 KB limit to itself.
Anchor to Request an exceptionRequest an exception
If your extension can't be optimized under the limit, you can request a bundle-size exception. Exceptions are for extensions that are still over the limit after avoidable bloat is removed, because of genuine feature density or a platform gap with no native alternative yet.
To request one, submit the bundle-size exception form. It asks for your minified bundle and its esbuild metafile, both produced when you build your extension.
Anchor to Next stepsNext steps
The bundle limit applies from API version 2025-10. If your extension is on an earlier version, then upgrade it to Polaris web components and Remote DOM:
| Surface | Upgrade guide |
|---|---|
| Checkout | Upgrade to the latest API and web components |
| Customer accounts | Upgrade to the latest API and web components |
| Admin | Upgrading to 2025-10 |
| POS | Upgrading to 2025-10 |