Checkout Polaris is the design system that powers the checkout surface across every Shopify storefront — and the public surface third-party developers use to extend it with Checkout UI Extensions.
For most of its life, the library was a React-only API. The 2026-07 release candidate flips that: components ship as framework-agnostic web components, while the React API becomes a thin wrapper that returns the same custom elements.
Why web components
Three reasons drove the rewrite, in order of how often I had to defend them:
- Sandboxed by default. Extensions run inside a worker, with no access to the host page's React tree. Web components are the smallest interop surface that survives that boundary — a
<s-button>rendered in the worker hydrates as a real<s-button>in the host without any framework coupling. - Bundle size. Pre-Polaris extensions shipped a copy of React per extension. Pulling that out means cold-load time drops measurably on the slowest mobile connections — the only place it actually matters for checkout.
- API stability. Custom elements give us a versioned tag name (
<s-button-v1>) without needing a new npm package per breaking change. Merchants don't see the version; extension authors opt in by tag.
The interesting move is sideways: the React layer didn't disappear, it just stopped being load-bearing.
What it looks like
// Before — React-only
import { Button, BlockStack } from "@shopify/ui-extensions-react/checkout";
export default reactExtension("purchase.checkout.block.render", () => (
<BlockStack>
<Button>Checkout</Button>
</BlockStack>
));
<!-- After — same thing, web components -->
<s-block-stack>
<s-button>Checkout</s-button>
</s-block-stack>
The React import still works; it just compiles down to the second snippet. Extension authors using Vue, Svelte, or vanilla JS can now build first-class extensions without us shipping framework-specific bindings.
The parts I worked on
I spent six years on the team that owns this surface. The pieces I'm proudest of:
- Token APIs. The Branding GraphQL API lets Shopify Plus merchants set typography, color, and spacing tokens server-side — by the time the checkout HTML reaches the browser, the tokens are already CSS variables on
<html>. No flash, no client-side JS to apply theme. - Form controls.
<s-text-field>,<s-select>,<s-checkbox>— all WCAG-AA out of the box, all tested against every assistive tech we could get our hands on. One-line audit notes get expensive when they ship to a billion checkouts a year. - The pattern of "compose, don't configure." Every component is a thin wrapper over a primitive.
<s-action-list>is just a<s-block-stack>of<s-button variant="ghost">s with the right ARIA glue. Anyone can rebuild it; nobody needs to.
Where to read the real docs
This post is a brief, opinionated tour. The real documentation lives at:
- Checkout UI Extensions overview — the full extension API.
- Web components reference — every component, every prop, every event.
If you're building an extension and want a second opinion on shape or accessibility, you know where to find me.