Appearance
Extensions & Functions
Extensions are code you upload to Shopify. They run inside Shopify's surfaces, such as the storefront, checkout, admin and POS, not on your server. You create them with shopify app generate extension, and they ship with shopify app deploy.
Pick the right type
| You want to… | Extension | Built with |
|---|---|---|
| Add a block or embed to the merchant's theme (storefront) | Theme app extension | Liquid + JS/CSS |
| Add UI to checkout, thank-you or order-status pages | Checkout UI extension | Polaris web components (Preact recommended) |
| Change business logic: discounts, shipping/payment options, validation, cart transforms | Shopify Function | Rust or JS → WebAssembly |
| Add actions or blocks inside Shopify Admin pages | Admin action / block extension | Polaris web components |
| Add UI to Shopify POS | POS UI extension | Polaris web components |
| Customer accounts pages | Customer account UI extension | Polaris web components |
| Trigger/act in Shopify Flow | Flow trigger / action | Config + your endpoint |
Theme app extensions
These replace the old practice of editing theme files through the Asset API. The Asset API is a Built for Shopify blocker. The merchant adds your block in the theme editor, and uninstalling removes it cleanly.
liquid
{% comment %} extensions/notify-badge/blocks/badge.liquid {% endcomment %}
<div class="notify-badge">Get order updates on WhatsApp</div>
{% schema %}
{
"name": "WhatsApp opt-in",
"target": "section",
"settings": [{ "type": "text", "id": "label", "label": "Label", "default": "Notify me" }]
}
{% endschema %}Checkout UI extensions
Checkout UI extensions on API version 2025-10 and later use Polaris web components, and Preact is the recommended framework (@shopify/ui-extensions/preact). They run sandboxed, so there is no DOM access and no arbitrary scripts. Checkout UI on the information, shipping and payment steps needs Shopify Plus. Thank-you and order-status pages are available on all plans.
tsx
import '@shopify/ui-extensions/preact';
import { render } from 'preact';
export default async () => render(<Extension />, document.body);
function Extension() {
return <s-checkbox label="Send me order updates on WhatsApp" />;
}Migration deadline
Older React-based checkout extensions need upgrading to the web-components API versions. Community reports say deploys of non-upgraded extensions may be blocked from October 2026. Check the migration guide.
Shopify Functions
Small, pure programs that Shopify runs during cart and checkout:
- Input: a GraphQL query you define (
run.graphql) - Output: JSON operations (e.g. "apply 10% to these lines")
- Compiled to WebAssembly with strict time and memory limits. No network calls.
js
// extensions/vip-discount/src/run.js
export function run(input) {
const isVip = input.cart.buyerIdentity?.customer?.hasAnyTag;
if (!isVip) return { discounts: [], discountApplicationStrategy: "FIRST" };
return {
discountApplicationStrategy: "FIRST",
discounts: [{ targets: [{ orderSubtotal: { excludedVariantIds: [] } }], value: { percentage: { value: "10" } } }],
};
}Legacy being replaced
Shopify Scripts (Ruby, Plus-only) and checkout.liquid are being retired in favour of Functions and checkout UI extensions. The exact dates vary by page type, so check the Shopify changelog before relying on any date.
Project step: add a theme app block that shows a "Get updates on WhatsApp" opt-in.
Check yourself
- A merchant wants "free shipping for VIP customers". Which extension type?
- Why can't a Function call your API?