LUCENTCOMMERCEGET A FREE STORE AUDITFREE AUDIT

APPS · THEME · OS 2.0 · TECHNICAL · 1 APRIL 2025 · 7 MIN READ

Theme app extensions: apps that do not touch your code

The old way was an app pasting a snippet into your theme and leaving it there forever. Extensions end that — and change which apps you should buy.

Four app tiles, one of them being removed

A theme app extension is the mechanism by which a Shopify app adds functionality to an Online Store 2.0 theme without editing the theme’s files. The app ships its own Liquid blocks, CSS and JavaScript in a separate, versioned bundle; the merchant adds or activates those blocks in the theme editor; and nothing is written into the theme itself. That has two consequences worth caring about: uninstalling an app no longer leaves orphaned code behind, and updating an app no longer requires anyone to touch your theme. For anyone choosing apps, "does it use a theme app extension?" has become the single most useful question to ask.

IN SHORT

  • Theme app extensions inject blocks, assets and snippets into a theme from outside it, so the app’s code and your theme’s code stay separate and separately versioned.
  • There are two kinds: app blocks, which a merchant positions inside a section, and app embed blocks, which a merchant activates and which handle things that are not tied to a spot on the page.
  • Shopify’s documented limits are 10 MB of files and 30 blocks per extension, with 100 KB of Liquid enforced, 100 KB of compressed CSS suggested and 10 KB of compressed JavaScript suggested.
  • Extension blocks cannot render on checkout pages, including payment and order status.
  • Script tags — the old injection mechanism — work only with vintage themes, and apps integrating with themes now use extensions instead.
  • An extension keeps an app out of your theme. It does not make the app’s JavaScript free, and the JS budget is a suggestion rather than an enforced limit.

What the old way cost you

Before extensions, an app that needed to appear on your storefront had two options: write a snippet into your theme files during install, or inject a script tag into every page. Both worked. Both left a mess.

The snippet approach meant the app’s code became your code. It survived the uninstall, because an app cannot reliably reverse an edit to a file you may have changed since. Audit an established Shopify theme today and you will find fragments of apps nobody remembers buying — a div waiting for a reviews widget that was cancelled two years ago, a block of Liquid guarding against an object that no longer exists. Every one of those is a thing a developer has to decide about before they can safely change the page around it.

Script tags were tidier to remove and worse to live with, because the app’s JavaScript loaded on every page whether or not it was needed, and you had no control over where in the page it landed or what it did when it got there.

Shopify’s position on both is now clear. The REST Admin API became a legacy API as of 1 October 2024, and from 1 April 2025 all new public apps must be built exclusively on the GraphQL Admin API. On script tags specifically, the documentation states they work only with vintage themes, and that apps integrating with Shopify themes must use theme app extensions instead. If an app you are evaluating still asks you to paste code into theme.liquid, that tells you when it was last meaningfully worked on.

What an extension actually contains

An extension is a small, self-contained bundle with three kinds of thing in it, per Shopify’s documentation: blocks, which are Liquid files acting as the entry point for whatever the app injects; assets, meaning the CSS, JavaScript and static content that get served alongside them; and snippets, reusable Liquid the blocks share.

It lives with the app, not with the theme. That is the whole design. The app developer versions and deploys the extension on their own release cycle; the merchant’s theme is untouched by the deployment, and a merchant who switches theme does not lose the app — they re-add the blocks in the new theme’s editor.

Two block types cover different jobs. An app block is one a merchant adds inside a theme section and positions like any other block: a review star rating under the product title, a size chart above the buy button, a delivery estimate in the cart. The merchant decides where it goes, and can move or remove it without a developer. An app embed block is activated rather than positioned, and is the right shape for anything that is not tied to a place on the page — the app’s script, a floating element, a chat launcher.

The distinction matters when you are judging an app. An app whose visible output is an app block is one you can place, move and remove yourself. An app that delivers everything through an embed block and then paints wherever it likes is back to being something you have less control over, extension or not.

The limits, and which ones bite

Shopify documents a specific budget per extension, and it is short enough to quote in full:

  • All files in the extension: 10 MB — enforced.
  • Number of blocks: 30 — enforced.
  • Locale files per extension: 100, each up to 15 KB — enforced.
  • Total Liquid code: 100 KB — enforced.
  • Compressed CSS: 100 KB — suggested.
  • Compressed JavaScript: 10 KB — suggested.

Read that list again, and note which word does the work

The JavaScript figure is the interesting one, and it is marked *suggested*, not enforced. Ten kilobytes compressed is a sensible budget for a widget. It is also nowhere near what a full reviews platform, a personalisation engine or a chat product actually ships. Nothing stops an extension exceeding it.

So the headline of this post is true and incomplete. A theme app extension keeps an app out of your theme’s files. It does not keep the app’s JavaScript off your pages, and it does not make that JavaScript cheap. If your store is slow because it carries eleven apps, moving all eleven to extensions changes the maintainability of your theme and very little about your Largest Contentful Paint.

The upside is that extensions make the cost legible. Because each app’s assets are its own, you can see which app is responsible for which bytes — which is a conversation you could not have when everything was concatenated into the theme’s own bundle. Use that. A performance review on an extension-based store is a list with names against the numbers.

The restrictions worth knowing before you plan a build

A handful of documented constraints catch people mid-implementation, and they are cheaper to know now.

Checkout is out of bounds. App blocks and app embed blocks cannot be rendered on checkout pages, and that covers the whole transaction including payment and the order status page. Checkout has its own extension model; do not plan to reach it from a theme app extension.

Three Liquid objects are unavailable. Extensions cannot access content_for_header, content_for_index or content_for_layout. If your design depended on reading or wrapping the layout, it needs rethinking.

An app block can barely see its parent section. Only the parent section’s ID property is accessible, which is deliberate — that ID is what the Section Rendering API needs to re-render the section later. An app block that wants to know what colour scheme or padding the surrounding section chose cannot ask; it has to expose its own settings and let the merchant match them.

The JSON is stricter than a theme’s. Extension JSON cannot contain comments or trailing commas, both of which standard theme files tolerate. It is a five-minute bug the first time and never again.

When to build one yourself — and when not to

If you are building a custom app for your own store, an extension is almost always the right delivery mechanism for anything that appears on the storefront. It keeps your app’s front end out of your theme, which means the theme can be rebuilt without also rebuilding the app, and it gives your merchandising team a block they can place without asking you. On the stores we maintain, that second property is the one that pays back.

But be honest about whether you need an app at all. A theme app extension requires an app — with a Partner account, a deployment pipeline, a hosted back end if it does anything server-side, and an OAuth relationship somebody has to keep alive. That is a lot of apparatus for something a theme section would do. If the thing you want is a configurable banner, a tabbed content block or a size chart, build a theme section: no app, no deployment, no dependency.

The dividing line we use is whether the feature needs to hold state or talk to something outside Shopify. A block that renders data your theme already has is a section. A block that needs a database, a third-party API, a background job or logic you do not want sitting in public Liquid is an app with an extension in front of it. Everything in between is usually a section, and the instinct to reach for an app is usually the expensive answer.

Questions this raises

What are theme app extensions?

They are the supported way for a Shopify app to add functionality to an Online Store 2.0 theme without editing the theme. The app ships its own versioned bundle of Liquid blocks, assets and snippets; merchants add or activate those blocks in the theme editor; and no code is written into the theme’s files, so uninstalling removes the app cleanly and updating it requires no theme change.

What is the difference between an app block and an app embed block?

An app block is added inside a theme section and positioned by the merchant, so it suits anything tied to a place on the page — a star rating, a size chart, a delivery estimate. An app embed block is activated rather than positioned, and suits things without a fixed location, such as the app’s script or a floating element.

Are theme app extensions faster than script tags?

They are better isolated, not automatically faster. Shopify suggests a 10 KB compressed JavaScript budget per extension, but that figure is documented as a suggestion rather than an enforced limit, so a heavy app is still a heavy app. What extensions do give you is attribution: each app’s assets are its own, so you can see which app costs what.

Can a theme app extension run on checkout?

No. Shopify’s documentation states that app blocks and app embed blocks cannot be rendered on checkout pages, and that includes every step of the transaction along with the payment and order status pages. Checkout has a separate extension model, and anything you need there belongs in that model instead.

What happens to a theme app extension when I change theme?

The app stays installed, because nothing about it lived in the old theme. What you lose is the placement: app blocks have to be added again in the new theme’s editor, and app embed blocks reactivated. Worth putting on the launch checklist for a theme rebuild, because the app will not tell you it has stopped appearing.

Should I build an app to add a feature to my storefront?

Only if the feature needs to hold state or talk to something outside Shopify. A block that renders data the theme already has should be a theme section — no app, no deployment, no OAuth to maintain. A block that needs a database, an external API or logic you do not want in public Liquid is an app, and its storefront part should be a theme app extension.

NEXT STEP

Free store audit

A senior Shopify engineer reviews your storefront, theme performance and checkout, then sends a prioritised list of fixes.