---
title: Migrate Icon from Polaris React
description: Learn how to migrate Polaris React Icon to Polaris web components.
source_url:
  html: 'https://shopify.dev/docs/apps/build/app-home/migrate-from-polaris-react/icon'
  md: >-
    https://shopify.dev/docs/apps/build/app-home/migrate-from-polaris-react/icon.md
api_name: app-home
---

# Migrate Icon from Polaris React

Use `s-icon` with a documented icon name. Keep an accessible text label on the owning control; don't rely on the icon alone to explain an action.

***

## Choose the destination

| Polaris React | Polaris web components | Migration type |
| - | - | - |
| `Icon` | [`s-icon`](https://shopify.dev/docs/api/app-home/web-components/media-and-visuals/icon) | Direct |

***

## Map icon properties

| Polaris React | Polaris web components | Migration notes |
| - | - | - |
| `source={SomeIcon}` | `type="documented-icon-name"` | Replace the imported React icon with a name from the icon reference. |
| Semantic `tone` values | `tone="info"`, `"success"`, `"warning"`, `"critical"`, or `"caution"` | Keep the same semantic tone when it exists. Use `neutral` for non-semantic status and `auto` when the surrounding context should determine treatment. |
| `tone="base"` | `tone="auto" color="base"` | Keep normal emphasis without inventing status meaning. |
| `tone="subdued"` | `tone="auto" color="subdued"` | Use the color property for reduced emphasis. |
| `tone="interactive"`, `"primary"`, or `"magic"` | No direct tone mapping | Choose a semantic tone only when the icon communicates status. For an action, put the documented icon name on `s-button` or `s-link` and let that control own its treatment. |
| Custom CSS color or token | No direct equivalent | Use the documented `tone` and `color` values; app CSS can't style the icon inside its shadow root. |
| `accessibilityLabel` | Label the containing button or link, or add visible adjacent text | `s-icon` doesn't expose an accessibility-label property. |

***

## Migrate the call site

1. Inventory every `Icon` call site and record the content, state, events, and accessibility behavior it uses.

2. Open the linked Polaris web component reference and map only documented properties, slots, and events.

3. Move unsupported responsibilities into adjacent content or app state instead of passing old props through.

4. After verification, remove the `Icon` import and any Polaris-only state, wrappers, or helpers that no longer have a caller.

***

## Preserve these behaviors

* Accessible names, semantics, and keyboard behavior.
* Visible content plus disabled, loading, selected, or error state that affects the task.
* Click, change, submit, and navigation behavior used by app logic.

***

## Test and remove Polaris React

Test every migrated `Icon` state used by the app. For interactive destinations, verify keyboard operation, focus, and accessible naming. For content destinations, verify document structure and alternative text where applicable. Compare behavior rather than pixel-for-pixel styling.

Don't remove `@shopify/polaris` while another component still imports it. Once all call sites are migrated, remove the package and its provider-level setup, then run the app's full test suite.

***

## Migration example

## Migrating Icon

##### Polaris web components

```tsx
export function IconMigrationExample() {
  return (
    <><s-icon type="info"></s-icon></>
  );
}
```

##### Polaris React

```tsx
import {Icon} from '@shopify/polaris';
import {InfoIcon} from '@shopify/polaris-icons';

export function IconMigrationExample() {

  return (
    <Icon source={InfoIcon} tone="base" />
  );
}
```

***
