---
title: Migrate Box from Polaris React
description: >-
  Learn how to migrate the Polaris React Box component to Polaris web components
  in an embedded app.
source_url:
  html: 'https://shopify.dev/docs/apps/build/app-home/migrate-from-polaris-react/box'
  md: >-
    https://shopify.dev/docs/apps/build/app-home/migrate-from-polaris-react/box.md
api_name: app-home
---

# Migrate Box from Polaris React

The Polaris box component is a generic container for spacing, sizing, backgrounds, borders, and accessibility. It replaces the Polaris React `Box` component from `@shopify/polaris` and is available as [`<s-box>`](https://shopify.dev/docs/api/app-home/web-components/layout-and-structure/box).

Use `s-box` only when the container owns a visual or accessibility boundary. Prefer `s-section`, `s-banner`, `s-stack`, `s-grid`, and interactive components when they describe the content or behavior more precisely.

## Migrating Box to s-box

##### Polaris web components

```tsx
export function InventorySummary() {
  return (
    <s-box
      background="subdued"
      border="base base solid"
      borderRadius="large"
      padding="base"
    >
      <s-stack gap="small-200">
        <s-heading>Inventory</s-heading>
        <s-text>18 units available at three locations.</s-text>
      </s-stack>
    </s-box>
  );
}
```

##### Polaris React

```tsx
import {BlockStack, Box, Text} from '@shopify/polaris';

export function InventorySummary() {
  return (
    <Box
      background="bg-surface-secondary"
      borderColor="border"
      borderStyle="solid"
      borderWidth="025"
      borderRadius="300"
      padding="400"
    >
      <BlockStack gap="200">
        <Text as="h2" variant="headingSm">Inventory</Text>
        <Text as="p">18 units available at three locations.</Text>
      </BlockStack>
    </Box>
  );
}
```

***

## Updated properties

The following properties are different in the Polaris box component.

### background

The background values now describe surface emphasis rather than exposing every Polaris React color token.

| Polaris React value | Polaris web components |
| - | - |
| `"bg-surface-transparent"` | `"transparent"` or omitted |
| `"bg-surface"` | `"base"` |
| `"bg-surface-secondary"` | `"subdued"` |
| `"bg-surface-tertiary"` | `"strong"` |

Other fill, interaction-state, inverse, and semantic color tokens don't have direct values. Use a semantic component such as `s-banner` for success, warning, or critical content. Don't freeze hover, active, selected, or disabled colors onto a static box.

### border color, style, and width

You can keep separate border properties or combine them with the [`border`](https://shopify.dev/docs/api/app-home/web-components/layout-and-structure/box#box-propertydetail-border) shorthand in the order `width color style`.

| Polaris React | Polaris web components |
| - | - |
| `borderColor="border-secondary"` | `borderColor="subdued"` |
| `borderColor="border"` | `borderColor="base"` |
| `borderColor="border-tertiary"` | `borderColor="strong"` |
| `borderStyle="solid"` | `borderStyle="solid"` |
| `borderStyle="dashed"` | `borderStyle="dashed"` |
| `borderWidth="0"` | `borderWidth="none"` |
| `borderWidth="0165"` | `borderWidth="small"` |
| `borderWidth="025"` | `borderWidth="base"` |
| `borderWidth="050"` | `borderWidth="large"` |

The old `borderWidth="100"` and semantic border colors such as `border-critical` don't have direct box values. Use the nearest supported width only when the boundary remains necessary, and use a semantic component when the color communicated status.

`borderColor="transparent"` also has no direct value. Remove the border when it isn't visible. If a transparent border reserved layout space for an interaction state, migrate the complete interaction to a component that owns its states.

### Per-edge border widths

Replace `borderBlockStartWidth`, `borderInlineEndWidth`, `borderBlockEndWidth`, and `borderInlineStartWidth` with the one-to-four-value `borderWidth` shorthand. Four values apply in that order.

For example, replace `borderBlockStartWidth="025"` with `borderWidth="base none none none"`. Replace each old token using the width table above, and test inline start and end in right-to-left languages.

### border radius

Replace the old radius scale with the Polaris web component scale.

| Polaris React value | Polaris web components |
| - | - |
| `"0"` | `"none"` |
| `"100"` | `"small-200"` |
| `"150"` | `"small-100"` |
| `"200"` | `"base"` |
| `"300"` | `"large"` |
| `"400"` | `"large-200"` |

The old `"050"`, `"500"`, `"750"`, and `"full"` values don't have exact equivalents. Choose the nearest supported radius from the containing surface. Don't use `s-box` to recreate a pill control; use the appropriate button, chip, badge, or field component.

Replace `borderStartStartRadius`, `borderStartEndRadius`, `borderEndEndRadius`, and `borderEndStartRadius` with the one-to-four-value `borderRadius` shorthand. Four values follow that corner order. For example, top-only rounding becomes `borderRadius="large large none none"`.

### padding

Keep `padding`, `paddingBlock`, `paddingBlockStart`, `paddingBlockEnd`, `paddingInline`, `paddingInlineStart`, and `paddingInlineEnd`, but replace old numeric spacing tokens.

| Polaris React value | Polaris web components |
| - | - |
| `"0"` | `"none"` |
| `"050"` | `"small-500"` |
| `"100"` | `"small-400"` |
| `"150"` | `"small-300"` |
| `"200"` | `"small-200"` |
| `"300"` | `"small-100"` |
| `"400"` | `"base"` |
| `"500"` | `"large"` |
| `"600"` | `"large-200"` |
| `"800"` | `"large-300"` |
| `"1000"` | `"large-400"` |
| `"1200"` | `"large-500"` |

The old `"025"`, `"250"`, `"700"`, and values larger than `"1200"` don't have exact equivalents. Re-evaluate the content relationship instead of adding arbitrary large padding.

Replace `{xs, sm, md, lg, xl}` objects with [responsive value](https://shopify.dev/docs/api/polaris/using-polaris-web-components#responsive-values) strings. `padding` also supports one-to-four space-separated flow-relative values.

### Sizing

Rename physical size properties to flow-relative properties.

| Polaris React | Polaris web components |
| - | - |
| `width` | `inlineSize` |
| `minWidth` | `minInlineSize` |
| `maxWidth` | `maxInlineSize` |
| `minHeight` | `minBlockSize` |

The new size properties accept pixel values, percentages, or `"0"`. `inlineSize` and `blockSize` also accept `"auto"`; maximum sizes accept `"none"`. Rework old `calc()`, viewport-unit, keyword, and other arbitrary CSS values instead of passing them through.

### overflow​X and overflow​Y

Replace matching `overflowX="hidden"` and `overflowY="hidden"` values with `overflow="hidden"`. The new property applies to both axes and also accepts `"visible"`.

There is no axis-specific, `scroll`, or `clip` equivalent. Use components that own overflow, such as modal content or responsive tables, instead of creating a generic scroll region without its keyboard and focus behavior.

### role and accessibility

Rename supported semantics and visibility properties:

| Polaris React | Polaris web components |
| - | - |
| `role="status"` | `accessibilityRole="status"` |
| `role="presentation"` | `accessibilityRole="presentation"` |
| `aria-label="…"` | `accessibilityLabel="…"` |
| `aria-hidden={true}` | `accessibilityVisibility="hidden"` |
| `visuallyHidden` | `accessibilityVisibility="exclusive"` |

The old `menu`, `listbox`, `combobox`, and `group` roles aren't available on `s-box`. Migrate those complete interactions to the corresponding web component or a labeled semantic region.

### id and children

Keep `id` when another element or app logic still references it. Move children into the default slot and migrate each nested Polaris React component.

***

## Removed properties

### as

`s-box` doesn't accept `as`. Use `s-box` for a generic container, `s-text` for inline text, `s-section` for a labeled section, `s-unordered-list` and `s-list-item` for lists, and the owning field component for legend or choice-group semantics.

### color

`s-box` doesn't set a text color on all descendants. Move color to the text or icon that owns it, using its documented `tone` or `color`. Prefer semantic tone over a copied Polaris React color token.

### shadow

`s-box` doesn't expose shadows. Use the surface hierarchy provided by sections, modals, popovers, and other components instead of rebuilding elevation.

### tab​Index

`s-box` isn't a generic focus target. Use `s-button`, `s-link`, `s-clickable`, or the relevant field for interactive content. Move programmatic focus to a meaningful heading, field, or control supported by the workflow.

### position, inset properties, and z​Index

Remove `position`, `insetBlockStart`, `insetBlockEnd`, `insetInlineStart`, `insetInlineEnd`, and `zIndex`. Rebuild columns and alignment with `s-grid` or `s-stack`, and use `s-modal`, `s-popover`, `s-menu`, or `s-tooltip` for layered content.

### opacity

`s-box` doesn't support opacity. Use `disabled`, `loading`, `hidden`, or `display="none"` on the component that owns that state. Don't reduce opacity as the only indication of status.

### outline properties

Remove `outlineColor`, `outlineStyle`, and `outlineWidth`. Focus indicators belong to interactive web components. For a non-interactive boundary, use the supported border properties.

### print​Hidden

There is no print-only visibility property. Remove print-specific UI when it isn't essential, or keep print behavior in the app's existing stylesheet until that content can be restructured. `display="none"` isn't a print-only replacement; it hides content for everyone.

***

## New properties

The Polaris box component introduces the following useful properties:

| Property | Description |
| - | - |
| `blockSize` and `maxBlockSize` | Add flow-relative height and maximum-height constraints. |
| `accessibilityVisibility` | Controls visible, assistive-technology-hidden, or screen-reader-only content. |
| `display` | Shows or removes the box with `"auto"` or `"none"` and accepts responsive values. |
| `border` | Combines supported width, color, and style tokens in one value. |

***

## Test the migration

* Verify padding, borders, backgrounds, and size constraints at every responsive iframe width.
* Test inline start and end behavior in both left-to-right and right-to-left languages.
* Confirm hidden, screen-reader-only, status, and presentation semantics with a screen reader.
* Check that removed positioning and overflow don't create clipping, horizontal scrolling, or unreachable controls.
* Verify interactive call sites now use a component with keyboard behavior and a visible focus indicator.
* Remove old token helpers, layout CSS, and the Polaris React `Box` import after their final consumers are migrated.

***

## Related guidance

* [Box component](https://shopify.dev/docs/api/app-home/web-components/layout-and-structure/box)
* [Box best practices](https://shopify.dev/docs/api/app-home/web-components/layout-and-structure/box#best-practices)
* [Scale](https://shopify.dev/docs/api/polaris/using-polaris-web-components#scale)
* [Responsive values](https://shopify.dev/docs/api/polaris/using-polaris-web-components#responsive-values)
* [Migrate from Polaris React](https://shopify.dev/docs/apps/build/app-home/migrate-from-polaris-react)

***
