Polaris Web Components Migration: Moving Off React (2026)
No7 Engineering Team
Growth Architecture Unit

Executing a Polaris web components migration is no longer an optional cleanup task for Shopify app teams. With Polaris for React officially deprecated and CDN-delivered custom elements standard across admin surfaces, maintaining monolithic React wrappers introduces unnecessary bundle bloat and brittle interface drift that will eventually break merchant workflows.
The architectural shift away from Polaris React
Shopify officially archived the legacy React component library to unify user interfaces across embedded Admin apps, POS, Checkout, and Customer Accounts through framework-agnostic custom elements. Instead of bundling hundreds of React components into your application build, your app now loads standard custom elements straight from Shopify edge servers.
Historically, importing from @shopify/polaris meant pulling an unpacked bundle of roughly 800KB to 1.2MB of JavaScript directly into your client distribution. Even with aggressive tree-shaking and modern bundlers, the baseline runtime weight penalised initial page render in the Shopify admin iframe. The new model replaces this local weight with a single CDN script tag served from cdn.shopify.com/shopifycloud/polaris.js, pushing component rendering logic to native browser primitives defined by MDN Web Components specifications.
In our work migrating embedded apps for Shopify Plus merchants, we found that moving off the React package eliminates dependency drift between App Bridge versions and UI components. When Shopify refreshes design tokens, button paddings, or modal behaviours in the admin, your embedded app inherits those updates immediately without requiring a package bump, recompile, or redeploy.
How do I migrate to polaris web components?
Migrating to Polaris web components requires stripping out the React npm package, injecting Shopify CDN script tags into your HTML document head, replacing compound React components with HTML custom element tags, and installing type definitions. The transition moves your front-end from props-driven JSX abstractions to standard DOM element attributes and custom event listeners.
The first structural step involves cleaning up your root template. In a standard Remix or React Router embedded app, you remove the AppProvider wrapper and place the script tag directly in your root layout alongside App Bridge:
<head> <meta name="shopify-api-key" content="%SHOPIFY_API_KEY%" /> <script src="https://cdn.shopify.com/shopifycloud/app-bridge.js"></script> <script src="https://cdn.shopify.com/shopifycloud/polaris.js"></script> </head>For TypeScript projects, you do not lose type safety during this transition. You uninstall @shopify/polaris and add @shopify/polaris-types as a development dependency. In your tsconfig.json, update your compiler options to recognise the custom element interfaces:
{ "compilerOptions": { "types": ["@shopify/app-bridge-types", "@shopify/polaris-types"] } }When completing a polaris react to web components refactor, you can accelerate component conversion using local automation. The official Dev Assistant and tools covered in our guide on the Shopify MCP server implementation allow you to inspect component signatures and validate custom element markup directly inside your editor.
Handling events, state, and reactivity without React wrappers
Polaris web components communicate state changes through standard browser events rather than synthetic React callback props. If you try passing callback functions like onAction={handleClick} to a custom element tag, the browser treats it as an invalid attribute and drops the handler silently.
Instead of declarative callback props, custom elements use standard DOM event listeners or custom element properties. Simple buttons trigger standard click events, while complex components dispatch custom events carrying event details. For React and Remix developers, the syntax shifts slightly depending on your framework version:
<s-page heading="Order Management"> <s-section heading="Fulfillment Status"> <s-banner tone="info" heading="Batch Processing Active"> <s-paragraph>Orders are being synchronised with the warehouse.</s-paragraph> </s-banner> <s-stack gap="base"> <s-button variant="primary" onClick={handleExport}>Export Manifest</s-button> <s-button variant="secondary" onClick={handleRefresh}>Refresh Feed</s-button> </s-stack> </s-section> </s-page>Complex controls such as modal overlays require opening and closing via DOM element methods or setting property attributes directly. Rather than controlling an open={isOpen} React state boolean on an imported modal component, you query the custom element reference and call native methods like show() or hide(). This separation keeps the component logic decoupled from your front-end view layer.
Decision framework: Polaris React vs web components
Choosing when to migrate comes down to package support lifecycles and extension boundaries. Because Shopify has ceased feature releases and bug fixes for the React library on the public Shopify Polaris repository, all forward development must target web components.
| Architectural Dimension | Polaris React (Legacy) | Polaris Web Components (Current) |
|---|---|---|
| Delivery Mechanism | Local npm package in app bundle | Shopify global edge CDN script |
| App Bundle Size Impact | 800KB to 1.2MB unpacked JS | 0KB added to application bundle |
| Framework Support | Locked strictly to React | React, Preact, Vue, Svelte, or Vanilla JS |
| UI Extension Compatibility | Blocked on API 2026-01+ | Native standard across all surfaces |
| Component Updates | Manual package upgrade and redeploy | Evergreen runtime updates via CDN |
This comparison demonstrates that legacy React packages are now pure liability. If you operate an embedded app generating recurring revenue, planning your Shopify polaris web components guide refactor should take precedence over building secondary features that rely on deprecated styling hooks.
The evergreen CDN dilemma and testing strategies
Loading UI components dynamically from Shopify edge CDN guarantees that your application UI matches Shopify admin redesigns, but it removes your ability to pin exact component versions in package lockfiles. Running an app with unpinned CDN scripts is gardening with no gardener: you wake up to find your primary button changed styling while your engineers were asleep.
Because breaking changes in CSS variables or custom element shadow DOM structures can land in production without a corresponding application deployment, your QA strategy must shift from build-time unit tests to automated runtime visual regression testing. We recommend configuring Playwright or Cypress runs on a continuous cron schedule against a staging development store.
Production Migration Checklist
- Script Tag Placement: Ensure
polaris.jsloads immediately afterapp-bridge.jsin the HTML head to avoid custom element registration delays. - TypeScript Setup: Verify
@shopify/polaris-typesis installed and referenced intsconfig.jsonso custom tags do not throw JSX type errors. - Event Binding: Replace synthetic React callback props with standard
onClickor custom event listeners on all action elements. - Visual Regression Tests: Set up automated headless browser runs that snapshot key app views weekly to catch unannounced CDN style updates.
- AI-Assisted Conversion: Use tooling reviewed in our analysis of Shopify Dev Assistant workflows to automate repetitive JSX tag rewrites.
Upgrading checkout and customer account UI extensions
For custom apps and Plus brands running UI extensions, the migration is strictly enforced by platform deprecation timelines. Extensions building on API version 2025-10 and 2026-01 move to remote-dom and Preact, utilizing Polaris web components directly within sandboxed extension workers.
As detailed in our Shopify checkout extensions guide, Shopify enforces a strict 64KB bundle size ceiling on checkout extensions. The legacy React reconciliation engine consumed a significant portion of that budget. Swapping to lightweight Preact wrappers and native Polaris web components reduces extension bundle footprints substantially, freeing up space for complex merchant business logic.
Merchants and app developers have until 1 October 2026 before deployments containing pre-2026-01 extension versions are blocked completely. Migrating early prevents deployment deadlocks when you need to ship urgent checkout patches during high-volume sales periods.
What to do next with your app codebase
Audit your embedded app repositories today to identify all active references to @shopify/polaris. A typical embedded app migration requires around 2 to 4 weeks of engineering effort, predominantly spent refactoring custom data tables, modal triggers, and form state synchronisation.
Begin by scaffolding a test branch, adding the CDN script tags per official Shopify App Home documentation, and replacing simple layout containers like Page, Layout, and Card with their respective s-page, s-section, and s-card custom element counterparts. If your team manages a large custom app portfolio or complex Plus extensions and needs dedicated engineering support to modernise your stack, our team provides full-cycle Shopify development services to audit, refactor, and harden your application architecture.
Frequently Asked Questions
The questions buyers and engineers ask us most about this topic.
How long does a Polaris web components migration typically take?
For a standard embedded Shopify app with 10 to 20 administrative screens, an end-to-end migration from Polaris React to web components typically takes around 2 to 4 weeks of focused engineering time. This includes updating root templates, replacing compound React components with custom elements, adjusting event listeners, and running visual regression tests.
Can I use Polaris web components with frameworks other than React?
Yes. Polaris web components are built on native Web Components standards and are completely framework-agnostic. You can use them directly in vanilla JavaScript, Vue, Svelte, Preact, HTMX, or server-rendered HTML templates simply by loading the Shopify CDN script tag in your document head.
What happens if I do not migrate off Polaris React?
Polaris React is deprecated and receives no updates, security patches, or new components. While legacy React apps may continue functioning in the short term, you face growing bundle bloat, styling inconsistencies as the Shopify admin evolves, and hard deployment blocks on UI extensions after 1 October 2026.