Migrating from v11 to v12
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.
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 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.
2️⃣ Manually migrate using migrator comments and RegExp code search
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.
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.
# 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
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
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
npx @shopify/polaris-migrator react-update-component-prop --componentName Badge --fromProp statusAndProgressLabelOverride --toProp toneAndProgressLabelOverride "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
💡 Migration example
Banner
Replace status prop with tone
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.
npx @shopify/polaris-migrator react-update-component-prop --componentName Box --fromProp borderRadiusEndStart --toProp borderEndStartRadius "**/*.{ts,tsx}"
npx @shopify/polaris-migrator react-update-component-prop --componentName Box --fromProp borderRadiusEndEnd --toProp borderEndEndRadius "**/*.{ts,tsx}"
npx @shopify/polaris-migrator react-update-component-prop --componentName Box --fromProp borderRadiusStartStart --toProp borderStartStartRadius "**/*.{ts,tsx}"
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.
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
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"
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
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.
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.
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"
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"
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
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
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
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"
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"
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"
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"
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
npx @shopify/polaris-migrator react-update-component-prop --componentName List --fromProp spacing --toProp gap "**/*.{ts,tsx}"
✅ Post-migration RegExp validation
💡 Migration example
Modal
Replace small prop with size="small"
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"
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"
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
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"
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
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"
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"
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"
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.
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
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
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
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 Token | Replacement Value |
---|---|
--p-color-bg-transparent-primary-experimental | rgba(0, 0, 0, 0.62) |
--p-color-bg-transparent-secondary-disabled-experimental | rgba(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 Token | Replacement Value |
---|---|
--p-color-icon-on-color | rgba(255, 255, 255, 1) |
--p-color-text-on-color | rgba(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
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
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
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
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
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 Token | Replacement 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
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.
- 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.
- 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>:
<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.
- <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.
or for InlineStackExample
- spacing='loose' + spacing={undefined}
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:
Component | Bevel z-index (children cannot be above this) |
---|---|
Card | 32 |
LegacyCard | 101 |
Popover | 2 |
TooltipOverlay | 1 |
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.