Reconsider recent UI Extensions file size limit changes

Upgrading to any UI Extension API that uses web components now enforces a 64kb bundle size as seen here: Upgrading to 2025-10

This is a very unexpected and breaking change, specially for apps whose core features are deeply integrated as UI Extensions.

The expectation to go from a 2MB limit to 64kb (96.8% reduction) in what will become a required API upgrade down the line is unrealistic for many app developers.

This echoes discussions such as:

Proposed solutions inspired by solutions in the Metafield values thread:

  • Increase the limit for all apps now and going forward.
  • And grandfather existing apps.
10 Likes

This change feels fundamentally misaligned with the reality of modern Shopify apps.

Reducing the bundle size from ~2MB to 64KB is not an incremental constraint, it’s a complete paradigm shift. For apps that rely heavily on UI Extensions as part of their core product experience, this effectively blocks adoption of newer APIs rather than enabling it.

From an outside perspective, this doesn’t look like an optimization push, it looks like a forced architectural rewrite with no realistic migration path. Expecting teams to rework mature, production-grade extensions into sub-64KB bundles is not just difficult, in many cases, it’s not viable without significantly degrading functionality.

The “just use web components” approach also underestimates the complexity involved. Tooling, developer experience, and ecosystem maturity around this stack are still not at a point where this constraint feels reasonable at scale.

If the goal is to push the platform forward, the current limit does the opposite, it creates friction, delays upgrades, and discourages investment in UI Extensions altogether.

A more balanced approach would be, increasing the limit to something practical, providing a long transition period, grandfathering existing apps.

Otherwise, this risks breaking trust with developers who have already invested heavily in the platform.

5 Likes

Hey,

Could you elaborate a bit on what specifically is blocking you from reaching the file size limits?

Is it dependencies you need for your extension to function? (Btw. you can check that contributes to bundle size using metafiles that the CLI now emits)
Is it that your extension implements many features?
Something else entirely?

Fwiw we’ve seen that a lot extensions go below the limit just by making the switch from react to preact.

1 Like

Hi @Robin-Shopify, thanks for getting back to us!

Here’s what’s holding us back in our particular case:

  • Dynamic UI Extension structure, a lot of the customization happens in the app, and the UI Extension only requires an “ID”, the rest happens during render, this allows us to ship only one extension that has all the features, creating less friction for the merchant and avoid having x1000 extensions in our collections.
  • Feature-rich extensions, we pack a lot of functionality that’s currently used by merchants, most of this functionality is hand written.
  • Dependencies - It can be said that most dependencies can be rewritten by hand, and we do for the most part for simple stuff, however to guarantee quality, we have a couple (very light-weight) dependencies that ensure extensions work flawlessly for merchants and their customers.

After moving to Web Components we’re still far above the imposed limit, and to be frank, as @Omar_Cardenas has put it, we were deep invested in the limit that Shopify originally set (2MB) and respected it, so for us is a trust-breaker after putting all the time and effort into making these extensions.

5 Likes

Hey @Robin-Shopify,

For my case most of its 500kb size is just written code, with dependencies actually taking up a much smaller portion. I have yet to migrate to preact but I suspect even then it will not meet the new 64kb limit.

The main reason for the bigger size is for a simpler merchant experience. My app offers checkout customization features with 30+ different customizations and around 100 unique triggers that the merchant can also combine in many different ways to satisfy their unique use-cases.

I figured it would be much simpler for the merchant when going to the checkout editor to simply add one app block than to parse through 10s of different checkout extensions from the same app because one extension has this customization while another doesn’t, or one has a trigger combination that isn’t found in another.

With just one big checkout extension the merchant only has to pick the 1 checkout extension to have access to all features. It also reduces errors because the merchant can no longer pick the incorrect extension for a specific customization.

Also early on when checkout extensions were first released, I remember there being a limit of only 20 or so extensions allowed per app. Knowing I would have 10s of different extensions as functions I figured I would have hit the limit very fast, which also contributed to building one bigger, more comprehensive checkout ui extension rather than splitting into multiple smaller ones.

With this change migration would be disruptive to say the least for existing merchants. I can split up logic into smaller extensions, but then each merchant would have to manually migrate by deleting old app blocks and adding new app blocks to accomplish the exact same thing, except even then some use-cases wouldn’t be covered because more extensions would likely mean more app blocks are needed and there’s still a 3-app block limit for each target.

I really hope the new imposed limit is reconsidered, or at least have older apps grandfathered in a similar way to what is being done with the metafield limit so as to minimize disruption to both merchants and developers.

5 Likes

We use @sentry/browser for exception reporting, which is explicitly recommended in Shopify’s own UI Extensions documentation for error handling: Error handling

This dependency alone is ~400 KB minified / ~130 KB gzipped according to Bundlephobia, already well beyond the proposed 64 KB limit, before including any application code: @sentry/browser v10.46.0 ❘ Bundlephobia

This creates a clear mismatch: the official documentation is recommending an approach that cannot realistically fit within the new constraints.

Additionally, UI Extensions are loaded after the native Shopify experience, which remains uninterrupted and fully interactive for customers. While reducing bundle size is always beneficial, the current model already ensures that extensions do not block or degrade the core customer journey.

Taken together, this raises concerns that the proposal may have been defined in isolation from how extensions are actually built and behave in production today. It would be helpful to understand what assumptions or internal benchmarks informed this limit, and whether common production setups were considered during the decision-making process.

4 Likes

Hey, just to sure: sentry isn’t actually that big. If you check tools like bundlephobia, they are not accounting for tree shaking unfortunately.

The actual size of sentry (without any integrations) is about 100kb uncompressed and 25-35kb compressed.

1 Like

Hi @Robin-Shopify, thanks for the follow up!

While tree shaking can lower the size - 35kb is still very near 50% of the total proposed limit of 64kb, how are we supposed to ship our existing production-ready extensions with this limitation?

2 Likes

@muchisx I hear you, I just wanted to make sure it’s understood that that one library in itself isn’t already way beyond the limit as bundlephobia seemed to have suggested.

Have you already tried to migrate your extension? What size did you end up with?

1 Like

@muchisx Just my 3c: I spent quite some time (and tokens) figuring out the Sentry integration. You can get it working with simpler extensions, but there’s a fundamental problem with Shopify itself - thrown errors just lack full context. Just wanted to let you know that there isn’t much value in running Sentry in extensions at all. You have to turn off 90% of its functionality to make it fit, and then Shopify doesn’t provide enough information about errors to make sense of them anyway.

Related: Extensions error handling

2 Likes

Hi @Patrick_Jakubik Thanks for your feedback! We mostly use Sentry to report back on our own captured exceptions and full tracing on complex conditional flows, the global error Sentry capture is indeed lacking a lot

Hi @Robin-Shopify, thanks again for the follow up.

The base bundle of a clean-slate extension generated via shopify app generate extension is already around 21 KB, without adding any real application code beyond the default template.

I tested this with a Customer Account extension.

That effectively leaves only 43 KB for actual functionality. If we also account for Shopify’s own recommended Sentry integration for error reporting (35KB as clarified), that drops to roughly 8 KB remaining.

For production-ready extensions serving real merchants, that is simply not enough room to build meaningful functionality.

Our extension currently sits at around ~500 KB in production, similar to what @Kyle mentioned. That also does not include several unreleased features we are actively working on that merchants are already expecting. Even with those additions, we would still remain comfortably below the original 2 MB limit that we built around, respected and committed to.

I also did the exercise of prototyping a version using the newer APIs and web components. Even after those changes, the bundle still ended up above roughly 300 KB.

At that point, the issue is no longer about whether developers are optimizing enough. It becomes a question of whether the proposed limit reflects the reality of how production extensions are built today.

2 Likes

Hey everyone, just jumping in to strongly back up @muchisx on this.

Look, we all know Shopify is pushing hard for better performance and faster load times. We completely respect that. But dropping from a 2MB limit down to a hard 64KB cap—a nearly 97% reduction—just ignores the reality of building modern, complex apps.

To put it in perspective, 64KB leaves us almost zero breathing room, even after migrating to Preact and Web Components. By the time you pull in basic, non-negotiable necessities like internationalization, a lightweight GraphQL client, and a simple validation library like Zod, the budget is entirely gone. We are basically being asked to build 2026-level features with 2010 file size limits.

The irony here is that this strict cap might actually hurt the user experience. By squeezing us into 64KB, we’re forced to rip out perfectly good client-side logic and offload it to our backends. Instead of a snappy, instant UI, merchants are going to be stuck waiting on constant network round-trips. We’re trading a slightly larger, easily cached initial download for terrible, ongoing latency.

Also, applying a blanket limit across the board doesn’t make sense. I get wanting to keep Checkout as lean as humanly possible—every millisecond counts there. But Admin and POS extensions handle heavy workflows and complex data visualization. They operate in completely different environments and need more room to breathe.

If Shopify really needs to enforce stricter limits moving forward, here are a few ways we could actually make this work without breaking the ecosystem:

Set surface-specific limits: Keep checkout strict, but give Admin and POS extensions something reasonable, like 500KB to 1MB.

Support dynamic imports: Give us proper support for code-splitting inside the extension sandbox so we aren’t punished for code the user hasn’t even interacted with yet.

Grandfather in existing apps: Like @muchisx mentioned, please don’t let this turn into a build-breaking nightmare for apps that were perfectly fine under the old 2MB limit. Give us a warning, not a hard build failure.

We want fast apps just as much as Shopify does, but performance shouldn’t come at the cost of crippling functionality and developer experience. Really hoping the team takes a second look at this!

3 Likes

Thanks everyone, please keep this kind of feedback coming.


Just a few things:

@muchisx I don’t intent to invalidate anything you’re saying, but let’s make sure to compare apples with apples or compressed with compressed.

For example, a newly generated checkout extension clocks in at ~8.5k gzipped not 21kb.

Our extension currently sits at around ~500 KB in production
the bundle still ended up above roughly 300 KB.

Are those numbers compressed or uncompressed?

@Sebastian_Gomez

non-negotiable necessities like internationalization

Ideally you wouldn’t need to bring your own i18n libraries. Are you finding that the native localization integration is lacking features you need?

a simple validation library like Zod
Many libraries have smaller alternatives that are just us or almost as capable. E.g. valibot could be something to look at in place of zod.

1 Like

I also agree with the group here. These limits may work for custom checkout extensions where everything is static and has a single use case. But when building extensions that need to support multiple use cases for different merchants needs, based on their industry it requires our extensions to be more dynamic and complex. I also understand the requirement for needing to reduce the size to improve performance but this drop in size requirement seems pretty drastic.

1 Like

No worries @Robin-Shopify!, it’s all well taken!

Our numbers, including the exercise of generating a new customer account extension and seeing 21kb (not checkout) come from the actual file size of the generated /dist/file.js bundle when running shopify app build.

I’m not aware of any other technique to see further compression on that file.

I’m not aware of any other technique to see further compression on that file.

Got it! I suppose how to do that exactly depends on your operating system, but on macOS for example, you should be able to do:

gzip -c /dist/file.js | wc -c

Here’s with the approach suggested in the docs, i’m on Windows:

Steps:

  • shopify app init
  • shopify app generate extension
  • Choose a Customer Account UI extension
  • shopify app build
  • Pass the generated metafile.json into: esbuild - Bundle Size Analyzer

The bundle analyzer unfortunately doesn’t show compressed sizes.

It helps finding large dependencies and files, but doesn’t show the full picture.

@Robin-Shopify Is there any way to make Shopify CLI spit out the final file that will be used for file size validations (if not, feature request :folded_hands:t2:), so we can have that deterministic file on sight.

I Gzipped the distilled file of one of our production extensions as a web component prototype - still ~150kb.

Can we discuss a possibility of grandfathering existing apps or/and to increase the global limit?

1 Like