HomeShopifyGuides → App block JS budget

10KB raw.
Gzip does not count.

The AssetSizeAppBlockJavaScript check reads the file on disk, not the bytes on the wire. A 14KB bundle that compresses to 4KB fails — and it fails at deploy, after you have written the feature.

From shipping a theme app extension · August 2026 · by SPELL
10KBThe hard limit
RawNot gzipped
DeployWhen it fails
0Storefront JS is best

What the check actually measures

Theme app extensions carry asset-size budgets, and the JavaScript one is 10KB per app block, measured uncompressed. This surprises people because every other performance conversation is about transfer size, where gzip or brotli is doing most of the work.

Here it is not. The check reads the file. Your minifier's report and your browser's network tab will both tell you a smaller, friendlier number, and neither is the number being enforced.

It also fails at deploy — not at build, not in dev. So the discovery arrives at the end.


Keep your source outside the extension

A src/ directory fails the deploy outright

Theme app extensions permit only assets/, blocks/, locales/ and snippets/. A build directory inside the extension folder is not "ignored" — it is rejected.

So keep readable source somewhere else in the repo and emit the minified artefact into extensions/<name>/assets/:

npx esbuild extension-src/widget.src.js \
  --bundle --minify --format=iife \
  --outfile=extensions/myapp/assets/widget.js

Then assert the budget in the same step, so it fails on your machine rather than at deploy:

SIZE=$(wc -c < extensions/myapp/assets/widget.js)
test "$SIZE" -lt 10240 \
  || { echo "over 10KB raw: $SIZE"; exit 1; }

Getting under 10KB


The better answer: ship no JavaScript

The budget stops being a constraint if the storefront surface renders in Liquid. Store your data in app-owned metaobjects, read it in the block's Liquid, and the browser receives markup instead of a script that fetches and builds markup.

That also settles the Built for Shopify storefront requirement — you cannot reduce a Lighthouse score by more than 10 points with code you did not ship. Architecting for it costs nothing at the start and is expensive to retrofit.

Two related traps while you are in there: put {{ block.shopify_attributes }} on the block's root element or the theme editor cannot map it, and never pipe a merchant setting through | tthat is what produces "Translation missing".

We build theme app extensions to this bar by default

Pure-Liquid storefront surfaces, budgets asserted in the build, and the design gates in from the first commit — because retrofitting them is the expensive path.

Book a call →

More on this