Migrating from v11 to v12

Polaris v12.0.0 prop replacement, removal of components, renamed components, and token changes.

Getting started

Upgrading to Polaris v12 from v11 requires several automated and manual migrations of token, component, and component prop names that have been removed, replaced, or renamed. The bulk of migrations are automated using the @shopify/polaris-migrator CLI tool, with the edge cases handled by find and replace in your code editor using provided RegExp searches. You can reference the recommended migration workflow or glossary sections for additional migration support.

Not on v11 yet? You'll need to follow the migration guides for previous major versions before upgrading to v12.

Upgrade to v12
npm install @shopify/polaris@12
# or
yarn add @shopify/polaris@12
Note: If you've installed other Polaris packages independently, you will also need to upgrade those to the major versions we released along with v12.

Migration workflow

When running token and component migrations, we recommend the following workflow:

1️⃣ Automate migrations using Polaris Migrator

The polaris-migrator CLI commands are scaffolded for you to paste into your terminal:

  • Tailor the directories in the command glob paths to those relevant to your app's file structure. For example, this generic monorepo glob **/*.{css,scss} might need to be changed to explicitly target stylesheets in {src}/**/*.{css,scss} in your app.
  • Adjust the file extensions for the migrations you are running. For example, React component migrations in a TypeScript app should target *.{ts,tsx} files, while token migrations should target *.{css,scss} files.
Example
# Example migration
npx @shopify/polaris-migrator ...
# Find modified files containing "polaris-migrator:" manual migration comments
matching_files=$(grep -r -l "polaris-migrator:" $(git ls-files -m))
# Stash the files needing manual migrations if there are any
if [[ -n "$matching_files" ]]; then
    git stash push $matching_files
else
    echo "No modified files contain 'polaris-migrator:'"
fi
# Stage all migrated files without "polaris-migrator:" comments
git add .
# Format staged files only
git diff --staged --name-only | xargs npx prettier --write
# Stage formatted files
git add .
#  Commit automatic migration
git commit -m "[Automated] Migrate X from Polaris v11 to v12"

The polaris-migrator could insert comments or skip instances that are unsafe to automatically migrate. You will need to resolve those issues in the next manual migration step.

Now, you need to validate the automatic migration and manually update any outstanding issues. The migration guide sections may have additional resources to help you resolve the migrations manually, such as 💡 Migration example, ➡️ Replacement mappings tables, and descriptions of what the automated migrations are doing.

Resolve polaris-migrator: comments

Unstash the polaris migrator comments if you stashed any in step 1.

Example
git stash pop

Go through each of the changed files and search for polaris-migrator: comments. Migrate the instance the comment refers to, then delete the comment.

Validate with RegExp

Next, search for each of the token RegExp searches which are found under the ✅ Post-migration RegExp validation toggle in the guide. Update any outstanding migrations until there are no more results for the RegExp search. If you're unsure on how to search in a code editor using RegExp, check out the glossary.

Example
# Stage all manually migrated files
git add .
# Format staged files only
git diff --staged --name-only | xargs npx prettier --write
# Optional: run stylelint if using stylelint-polaris and running migrations on stylesheets
npx stylelint "**/*.{css,scss}"
#  Commit manual migrations
git commit -m "[Manual] Migrate X from Polaris v11 to v12"

Glossary

Descriptions and resources for some terms in this guide

Component migrations

AppProvider

The AppProvider features prop no longer accepts the keys polarisSummerEditions2023 and polarisSummerEditions2023ShadowBevelOptOut. If these were the only features passed into your AppProvider, you can safely remove the features prop completely from your Polaris AppProvider. If that is not the case, you will need to remove the features specifically related to polarisSummerEditions2023 and polarisSummerEditions2023ShadowBevelOptOut from being passed into the features prop.

✅ Post-migration RegExp validation
💡 Migration example

Avatar

Rename size prop values

polaris-migrator codemod
npx @shopify/polaris-migrator v12-react-avatar-component "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
➡️ Prop replacement mappings for the Avatar size prop
💡 Migration example

Remove shape prop

The Avatar shape prop was deprecated because circular shapes are no longer part of the admin design language. Remove the shape prop from Avatar.

✅ Post-migration RegExp validation
💡 Migration example

Badge

Replace status prop with tone

polaris-migrator codemod
npx @shopify/polaris-migrator react-update-component-prop --componentName Badge --fromProp status --toProp tone "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
💡 Migration example

Replace statusAndProgressLabelOverride prop with toneAndProgressLabelOverride

polaris-migrator codemod
npx @shopify/polaris-migrator react-update-component-prop --componentName Badge --fromProp statusAndProgressLabelOverride --toProp toneAndProgressLabelOverride "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
💡 Migration example

Replace status prop with tone

polaris-migrator codemod
npx @shopify/polaris-migrator react-update-component-prop --componentName Banner --fromProp status --toProp tone "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
💡 Migration example

Box

Replace borderRadius${cornerPosition} prop with border${cornerPosition}Radius

This border radius property rename aligns with CSS border radius constituent properties to be consistent with other Polaris component APIs as well as wider web conventions.

polaris-migrator codemod
npx @shopify/polaris-migrator react-update-component-prop --componentName Box --fromProp borderRadiusEndStart --toProp borderEndStartRadius "**/*.{ts,tsx}"
polaris-migrator codemod
npx @shopify/polaris-migrator react-update-component-prop --componentName Box --fromProp borderRadiusEndEnd --toProp borderEndEndRadius "**/*.{ts,tsx}"
polaris-migrator codemod
npx @shopify/polaris-migrator react-update-component-prop --componentName Box --fromProp borderRadiusStartStart --toProp borderStartStartRadius "**/*.{ts,tsx}"
polaris-migrator codemod
npx @shopify/polaris-migrator react-update-component-prop --componentName Box --fromProp borderRadiusStartEnd --toProp borderStartEndRadius "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
💡 Migration example

Button

Consolidate boolean props to variant and tone

The Button component has been updated to replace deprecated connectedDisclosure, outline, destructive, primary, primarySuccess, plain, and monochrome props with a new variant prop that supports multiple variation options.

polaris-migrator codemod
npx @shopify/polaris-migrator v12-react-update-button-component "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
➡️ Prop consolidation mappings
💡 Migration example
💡 How to manually update `connectedDisclosure` example

ButtonGroup

Replace spacing prop with gap

polaris-migrator codemod
npx @shopify/polaris-migrator react-update-component-prop --componentName ButtonGroup --fromProp spacing --toProp gap "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
💡 Migration example

Replace segmented prop to variant="segmented"

polaris-migrator codemod
npx @shopify/polaris-migrator react-update-component-prop --componentName ButtonGroup --fromPropType boolean --fromProp segmented --toProp variant --toValue segmented "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
💡 Migration example

DescriptionList

Replace spacing prop with gap

polaris-migrator codemod
npx @shopify/polaris-migrator react-update-component-prop --componentName DescriptionList --fromProp spacing --toProp gap "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
💡 Migration example

HorizontalGrid

Rename HorizontalGrid component to InlineGrid

Directional components now use Inline and Block naming conventions which are defined by CSS logical properties. This ensures consistency with other Polaris component APIs as well as wider web conventions.

polaris-migrator codemod
npx @shopify/polaris-migrator react-rename-component --renameFrom HorizontalGrid --renameTo InlineGrid --renamePropsFrom HorizontalGridProps --renamePropsTo InlineGridProps "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
💡 Migration example

HorizontalStack

Rename HorizontalStack component to InlineStack

Directional components now use Inline and Block naming conventions which are defined by CSS logical properties. This ensures consistency with other Polaris component APIs as well as wider web conventions.

polaris-migrator codemod
npx @shopify/polaris-migrator react-rename-component --renameFrom HorizontalStack --renameTo InlineStack --renamePropsFrom HorizontalStackProps --renamePropsTo InlineStackProps "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
💡 Migration example

Icon

🔔 Stepped migration: You must run the color -> tone migration after running the tone rename migrations.

Step 1: Replace color="warning" with tone="caution"

polaris-migrator codemod
npx @shopify/polaris-migrator react-update-component-prop --componentName Icon --fromProp color --toProp tone --fromValue warning --toValue caution "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
💡 Migration example

Step 2: Replace color="highlight" with tone="info"

polaris-migrator codemod
npx @shopify/polaris-migrator react-update-component-prop --componentName Icon --fromProp color --toProp tone --fromValue highlight --toValue info "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
💡 Migration example

Step 3: Replace color prop with tone

polaris-migrator codemod
npx @shopify/polaris-migrator react-update-component-prop --componentName Icon --fromProp color --toProp tone "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
💡 Migration example

Remove backdrop prop

Backdrop is not a pattern in the new Polaris design language. If you must use a backdrop on your icon, use Box.

✅ Post-migration RegExp validation
💡 Migration example

IndexTable.Row

Replace status prop with tone

polaris-migrator codemod
npx @shopify/polaris-migrator react-update-component-prop --componentName IndexTable.Row --fromProp status --toProp tone "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
💡 Migration example

Replace subdued prop with tone

polaris-migrator codemod
npx @shopify/polaris-migrator react-update-component-prop --componentName IndexTable.Row --fromPropType boolean --fromProp subdued --toProp tone --toValue subdued "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
💡 Migration example

Layout.Section

Replace oneThird prop with variant="oneThird"

polaris-migrator codemod
npx @shopify/polaris-migrator react-update-component-prop --componentName Layout.Section --fromPropType boolean --fromProp oneThird --toProp variant --toValue oneThird "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
💡 Migration example

Replace oneHalf prop with variant="oneHalf"

polaris-migrator codemod
npx @shopify/polaris-migrator react-update-component-prop --componentName Layout.Section --fromPropType boolean --fromProp oneHalf --toProp variant --toValue oneHalf "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
💡 Migration example

Replace fullWidth prop with variant="fullWidth"

polaris-migrator codemod
npx @shopify/polaris-migrator react-update-component-prop --componentName Layout.Section --fromPropType boolean --fromProp fullWidth --toProp variant --toValue fullWidth "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
💡 Migration example

Replace secondary prop with variant="oneThird"

polaris-migrator codemod
npx @shopify/polaris-migrator react-update-component-prop --componentName Layout.Section --fromPropType boolean --fromProp secondary --toProp variant --toValue oneThird "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
💡 Migration example

List

Replace spacing prop with gap

polaris-migrator codemod
npx @shopify/polaris-migrator react-update-component-prop --componentName List --fromProp spacing --toProp gap "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
💡 Migration example

Replace small prop with size="small"

polaris-migrator codemod
npx @shopify/polaris-migrator react-update-component-prop --componentName Modal --fromPropType boolean --fromProp small --toProp size --toValue small "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
💡 Migration example

Replace large prop with size="large"

polaris-migrator codemod
npx @shopify/polaris-migrator react-update-component-prop --componentName Modal --fromPropType boolean --fromProp large --toProp size --toValue large "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
💡 Migration example

Replace fullScreen prop with size="fullScreen"

polaris-migrator codemod
npx @shopify/polaris-migrator react-update-component-prop --componentName Modal --fromPropType boolean --fromProp fullScreen --toProp size --toValue fullScreen "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
💡 Migration example

Page

Remove divider prop

Page dividers are no longer a pattern in the new Polaris design language. If you must use a divider, use the Divider component to add them back in where needed.

✅ Post-migration RegExp validation
💡 Migration example

ProgressBar

Replace color prop with tone

polaris-migrator codemod
npx @shopify/polaris-migrator react-update-component-prop --componentName ProgressBar --fromProp color --toProp tone "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
💡 Migration example

Text

🔔 Stepped migration: You must run the color -> tone migration after running the tone rename migrations.

Step 1: Replace color="warning" with tone="caution"

polaris-migrator codemod
npx @shopify/polaris-migrator react-update-component-prop --componentName Text --fromProp color --toProp tone --fromValue warning --toValue caution "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
💡 Migration example

Step 2: Replace color prop with tone

polaris-migrator codemod
npx @shopify/polaris-migrator react-update-component-prop --componentName Text --fromProp color --toProp tone "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
💡 Migration example

Replace variant="headingXs" prop with variant="headingSm"

polaris-migrator codemod
npx @shopify/polaris-migrator react-update-component-prop --componentName Text --fromProp variant --fromValue headingXs --toValue headingSm "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
💡 Migration example

Replace variant="heading4xl" with variant="heading3xl"

polaris-migrator codemod
npx @shopify/polaris-migrator react-update-component-prop --componentName Text --fromProp variant --fromValue heading4xl --toValue heading3xl "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
💡 Migration example

TextField

Replace borderless prop with variant="borderless"

polaris-migrator codemod
npx @shopify/polaris-migrator react-update-component-prop --componentName TextField --fromPropType boolean --fromProp borderless --toProp variant --toValue borderless "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
💡 Migration example

VerticalStack

Rename VerticalStack component to BlockStack

Directional components now use Inline and Block naming conventions which are defined by CSS logical properties. This ensures consistency with other Polaris component APIs as well as wider web conventions.

polaris-migrator codemod
npx @shopify/polaris-migrator react-rename-component --renameFrom VerticalStack --renameTo BlockStack --renamePropsFrom VerticalStackProps --renamePropsTo BlockStackProps "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
💡 Migration example

Token migrations

The following tokens have either been renamed or removed. You will need to replace any instances of them with their new name or value equivalents. Please review each token section for migrations that can be run to resolve these breaking changes.

Border

To replace deprecated border custom properties, you can run the v12-styles-replace-custom-property-border migration then validate with RegExp. Please reference the recommended migration workflow section below for additional migration support.

💡 Migration example
polaris-migrator codemod
npx @shopify/polaris-migrator v12-styles-replace-custom-property-border "**/*.{css,scss}"
✅ Post-migration RegExp validation
➡️ Token replacement mappings

Color

To replace deprecated color custom properties, you can run the v12-styles-replace-custom-property-color migration then validate with RegExp. Please reference the recommended migration workflow section below for additional migration support.

💡 Migration example

🔔 Stepped migration: The color migration needs to be run in 4 sequential steps due to overlapping color token names and context dependent manual migrations.

Color migration step 1

Polaris Migrator codemod for step 1
npx @shopify/polaris-migrator v12-styles-replace-custom-property-color "**/*.{css,scss}" --step=1
✅ Post-migration RegExp validation for step 1
➡️ Token replacement mappings for step 1

Color migration step 2

Polaris Migrator codemod for step 2
npx @shopify/polaris-migrator v12-styles-replace-custom-property-color "**/*.{css,scss}" --step=2
✅ Post-migration RegExp validation for step 2
➡️ Token replacement mappings for step 2

Color migration step 3

Manually migrate the following tokens to their hardcoded values:

Deprecated TokenReplacement Value
--p-color-bg-transparent-primary-experimentalrgba(0, 0, 0, 0.62)
--p-color-bg-transparent-secondary-disabled-experimentalrgba(0, 0, 0, 0.08)
✅ Post-migration RegExp validation for step 3

Color migration step 4

on-color is being replaced by on-bg-fill tokens. These tokens will no longer be the same value but tailored to the background color the element is sitting on. This gives us greater control over the visual design of the admin.

If you want to unblock your migration quickly you can manually hardcode the values using the following replacement map:

Deprecated TokenReplacement Value
--p-color-icon-on-colorrgba(255, 255, 255, 1)
--p-color-text-on-colorrgba(255, 255, 255, 1)
✅ Post-migration RegExp validation for step 4
If you want to update your code to use the correct token instead of hardcoding, you can use the table below as a general guide to manually update `text-on-color` and `icon-on-color` tokens based on background color context:

Font

To replace deprecated font custom properties, you can run the v12-styles-replace-custom-property-font migration then validate with RegExp. Please reference the recommended migration workflow section below for additional migration support.

💡 Migration example

🔔 Stepped migration: The font migration needs to be run in 4 sequential steps due to overlapping font-size token names.

Font migration step 1

Polaris Migrator codemod for step 1
npx @shopify/polaris-migrator v12-styles-replace-custom-property-font "**/*.{css,scss}" --step=1
✅ Post-migration RegExp validation for step 1
➡️ Token replacement mappings for step 1

Font migration step 2

Polaris Migrator codemod for step 2
npx @shopify/polaris-migrator v12-styles-replace-custom-property-font "**/*.{css,scss}" --step=2
✅ Post-migration RegExp validation for step 2
➡️ Token replacement mappings for step 2

Font migration step 3

Polaris Migrator codemod for step 3
npx @shopify/polaris-migrator v12-styles-replace-custom-property-font "**/*.{css,scss}" --step=3
✅ Post-migration RegExp validation for step 3
➡️ Token replacement mappings for step 3

Font migration step 4

Polaris Migrator codemod for step 4
npx @shopify/polaris-migrator v12-styles-replace-custom-property-font "**/*.{css,scss}" --step=4
✅ Post-migration RegExp validation for step 4
➡️ Token replacement mappings for step 4

Shadow

To replace deprecated shadow custom properties, you can run the v12-styles-replace-custom-property-shadow migration then validate with RegExp. Please reference the recommended migration workflow section below for additional migration support.

💡 Migration example

🔔 Stepped migration: The shadow migration needs to be run in 2 sequential steps due to context dependent manual migrations.

Shadow migration step 1

Polaris Migrator codemod for step 1
npx @shopify/polaris-migrator v12-styles-replace-custom-property-shadow "**/*.{css,scss}"
✅ Post-migration RegExp validation for step 1
➡️ Token replacement mappings for step 1

Shadow migration step 2

The following tokens need to be manually migrated because their values are context dependent:

Deprecated TokenReplacement Value
--p-shadow-button-primary-experimental--p-shadow-button-primary-critical
--p-shadow-button-primary-success
--p-shadow-button-primary-hover-experimental--p-shadow-button-primary-critical-hover
--p-shadow-button-primary-success-hover
--p-shadow-button-inset-experimental--p-shadow-button-primary-critical-inset
--p-shadow-button-primary-success-inset
✅ Post-migration RegExp validation

Space

To replace deprecated space custom properties, you can run the v12-styles-replace-custom-property-space migration then validate with RegExp. Please reference the recommended migration workflow section below for additional migration support.

💡 Migration example
polaris-migrator codemod
npx @shopify/polaris-migrator v12-styles-replace-custom-property-space "**/*.{css,scss}"
✅ Post-migration RegExp validation
➡️ Token replacement mappings

@shopify/polaris-tokens updates

Renames

  • getCustomPropertyNames renamed to getThemeVarNames
  • createVar renamed to createVarName

Deprecations

Deprecated Utilities

If you are using these utilities, feel free to copy them from v11 into your own codebase.

  • createExact
  • createMetadata
  • getKeyframeNames
  • getUnit
  • isKeyOf
  • rem
  • removeMetadata
  • toEm
  • tokensToRems
Deprecated Types
  • BreakpointsAliasDirectionMediaConditions
  • BreakpointsMediaConditions
  • MetaBreakpointsTokenGroup
  • Tokens (replaced by Theme)
Deprecated all JSON exports
  • @shopify/polaris-tokens/json/border.json
  • @shopify/polaris-tokens/json/breakpoints.json
  • @shopify/polaris-tokens/json/color.json
  • @shopify/polaris-tokens/json/font.json
  • @shopify/polaris-tokens/json/height.json
  • @shopify/polaris-tokens/json/motion.json
  • @shopify/polaris-tokens/json/shadow.json
  • @shopify/polaris-tokens/json/space.json
  • @shopify/polaris-tokens/json/text.json
  • @shopify/polaris-tokens/json/width.json
  • @shopify/polaris-tokens/json/zIndex.json

If you are using these exports, update the implementation to import themes and JSON.stringify the theme you need.

Example
- const color = require('@shopify/polaris-tokens/json/color.json');
+ const {themes} = require('@shopify/polaris-tokens');
+ const color = JSON.stringify(themes.light.color);
tokens object

Instead of importing tokens directly you should use the useTheme hook when you have to access token values. If you must access the tokens directly, you can import tokens -> defaultTheme from @shopify/polaris-tokens.

Example
- import {tokens} from '@shopify/polaris-tokens';
+ import {useTheme} from '@shopify/polaris';

+ const theme = useTheme();

- tokens.space['1'];
+ theme.space['100'];

Manual updates and fixes

A new web font

The new design language comes with a web font called Inter.

Polaris references this font but does not load it. Your app will need to load the font, otherwise it will fallback to the user's system font. You can load this font from Shopify by adding the following to your app's <head>:

Example
<link
  rel="preconnect"
  href="https://cdn.shopify.com/"
/>
<link
  rel="stylesheet"
  href="https://cdn.shopify.com/static/fonts/inter/v4/styles.css"
/>

Icons

Major and minor icon sizes are now identical. You may need to update custom icons in your app as they may look much larger than Polaris icons now. All icons still maintain the 20x20 viewbox.

Dividers

We removed dividers across Polaris components, most noticeably in Page and LegacyCard. We now recommend using spacing to create a visual hierarchy. If you must use a divider, use the Divider component to add them back in where needed.

Buttons beside inputs

Default buttons have decreased in height and no longer match the height of some inputs, namely TextField and Select. To update a button's height to match the new height of input fields, use the large size by using the large size variant of Button.

Example
- <TextField connectedRight={<Button icon={DeleteMajor} />} />
+ <TextField connectedRight={<Button icon={DeleteMajor} size="large" />} />

LegacyCard

Heading size

The LegacyCard now enforces that h1 and h2 content uses the Text headingSm variant (--p-font-size-325). If you want to use custom heading sizes, please refactor LegacyCard to Card.

Spacing and visual hierarchy

The LegacyCard now has much tighter spacing and does not have dividers between sections and subsections. This may result in some visual hierarchy/padding issues depending on how your cards are composed. You can resolve this in a number of ways:

  • recommended – Use Card and BlockStack to compose a new card layout
  • Remove any custom content spacing wrappers and use <LegacyCard.Section />, <LegacyCard.Header />, or <LegacyCard.Section flush /> instead. Issues involving a lack of top or bottom padding on the card is likely caused by this.
  • Update all custom content padding using --p-space-500 to use --p-space-400. This includes content wrapped in a LegacyStack component.
    Example
    - spacing='loose'
    + spacing={undefined}
    or for InlineStack
    Example
    - gap='5'
    + gap='4'
  • Add back dividers using Divider where needed
  • As a last resort, you can add space with Box or remove space with Bleed.

Z-Index

The new design language introduces a shadow bevel in numerous components. The following component's children cannot be above the bevel's z-index elevation:

ComponentBevel z-index
(children cannot be above this)
Card32
LegacyCard101
Popover2
TooltipOverlay1

Custom elements

Custom elements that were styled to look like the previous Polaris design language will need to be updated. Take the opportunity to put custom styles and components on mainline Polaris using our components and tokens.

.Polaris-Summer-Editions-2023 class

The <html> element no longer receives the .Polaris-Summer-Editions-2023 class. If your styles rely on this class as part of a CSS selector, you can safely remove it.

    On this page