Reference version

Icon

A platform-native icon — SF Symbol on iOS, Material Symbol on Android.

Android
iOS
Included in Expo Go
Bundled version:
~56.0.2

For the complete documentation index, see llms.txt. Use this file to discover all available pages.

A platform-native icon. On Android, it renders a Material Symbol XML vector drawable supplied through @expo/material-symbols (other XML vector drawable assets aren't officially supported). On iOS, it renders an SF Symbol

Note: Icon does not render on web.

Installation

Terminal
npx expo install @expo/ui

If you are installing this in an existing React Native app, make sure to install expo in your project.

Usage

Cross-platform icon with Icon.select

Icon.select picks the right asset for the current platform. Pair it with @expo/ui/babel-plugin (auto-loaded by babel-preset-expo) so Metro can tree-shake the unused side per platform.

IconSelectExample.tsx
import { Host, Icon } from '@expo/ui'; export default function IconSelectExample() { return ( <Host matchContents> <Icon name={Icon.select({ ios: 'star.fill', android: import('@expo/material-symbols/star.xml'), })} size={32} color="orange" /> </Host> ); }

Hoisted Icon.select

Hoist the Icon.select call when reusing the same icon across multiple call sites.

HoistedIconExample.tsx
import { Host, Row, Icon } from '@expo/ui'; const STAR = Icon.select({ ios: 'star.fill', android: import('@expo/material-symbols/star.xml'), }); export default function HoistedIconExample() { return ( <Host matchContents> <Row spacing={4}> <Icon name={STAR} size={20} color="gold" /> <Icon name={STAR} size={20} color="gold" /> <Icon name={STAR} size={20} color="gold" /> </Row> </Host> ); }

Platform-specific files

Inside an .android.tsx file, import the XML asset directly. Inside an .ios.tsx file, pass the SF Symbol name as a string.

Icon.android.tsx
import StarIcon from '@expo/material-symbols/star.xml'; import { Host, Icon } from '@expo/ui'; export default function StarRow() { return ( <Host matchContents> <Icon name={StarIcon} size={24} /> </Host> ); }
Icon.ios.tsx
import { Host, Icon } from '@expo/ui'; export default function StarRow() { return ( <Host matchContents> <Icon name="star.fill" size={24} /> </Host> ); }

API

import { Icon } from '@expo/ui';

Component

Icon

Android
iOS

Type: React.Element<IconProps>

A platform-native icon. Renders an XML vector drawable (typically from @expo/material-symbols) on Android and an SF Symbol on iOS.

Example

const STAR = Icon.select({ ios: 'star.fill', android: import('@expo/material-symbols/star.xml'), }); <Icon name={STAR} size={24} color="orange" />

Example

<Icon name={Icon.select({ ios: 'star.fill', android: import('@expo/material-symbols/star.xml'), })} size={24} />

Example

Both sides ship to both platforms. Prefer Icon.select when bundle size matters.

<Icon name={{ ios: 'star.fill', android: require('@expo/material-symbols/star.xml'), }} size={24} />

Example

import StarIcon from '@expo/material-symbols/star.xml'; <Icon name={StarIcon} size={24} />

Example

<Icon name="star.fill" size={24} />

Props for the Icon component.

IconProps

accessibilityLabel

Android
Optional • Type: string

Accessibility label for screen readers. On Android, maps to contentDescription. iOS accessibility is not yet wired up.

color

Android
iOS
Optional • Type: ColorValue

Tint color applied to the icon.

disabled

Android
iOS
Web
Optional • Type: boolean

Whether the component is disabled. Disabled components do not respond to user interaction.

hidden

Android
iOS
Web
Optional • Type: boolean

Whether the component is hidden.

modifiers

Android
iOS
Optional • Type: ModifierConfig[]

Platform-specific modifier escape hatch. Pass an array of modifier configs from @expo/ui/swift-ui/modifiers or @expo/ui/jetpack-compose/modifiers.

name

Android
iOS
Type: IconName

Icon source. Android expects an XML vector drawable asset (typically from @expo/material-symbols); iOS expects an SF Symbol string.

Use Icon.select for a cross-platform definition.

onAppear

Android
iOS
Web
Optional • Type: () => void

Called when the component appears on screen.

onDisappear

Android
iOS
Web
Optional • Type: () => void

Called when the component is removed from screen.

onPress

Android
iOS
Web
Optional • Type: () => void

Called when the component is pressed.

size

Android
iOS
Optional • Type: number

Icon size in dp (Android) / points (iOS). When omitted, the icon uses its intrinsic size.

style

Android
iOS
Web
Optional • Type: Pick<ViewStyle, 'padding' | 'paddingHorizontal' | 'paddingVertical' | 'paddingTop' | 'paddingBottom' | 'paddingLeft' | 'paddingRight' | 'backgroundColor' | 'borderRadius' | 'borderWidth' | 'borderColor' | 'opacity' | 'width' | 'height'>

Platform-agnostic style properties. These are translated to SwiftUI modifiers on iOS and Jetpack Compose modifiers on Android.

testID

Android
iOS
Web
Optional • Type: string

Identifier used to locate the component in end-to-end tests.

Component Methods

select(spec)

Android
iOS
ParameterType
specIconSelectSpec

Picks the icon source for the current platform — android on Android, ios on iOS.

Pair with @expo/ui/babel-plugin to strip the unused side per platform.

Example

const STAR = Icon.select({ ios: 'star.fill', android: import('@expo/material-symbols/star.xml'), }); <Icon name={STAR} size={24} />

Interfaces

IconSelectSpec

Android
iOS

Argument shape accepted by Icon.select.

The android slot accepts either a synchronous require() result or a dynamic import('*.xml') expression. The latter is preferred because TypeScript validates the literal path through the package's exports map, catching typos at compile time. The accompanying Babel plugin (@expo/ui/babel-plugin, auto-loaded by babel-preset-expo) rewrites the import() to a require() so Metro can still tree-shake the unused side.

PropertyTypeDescription
androidImageSourcePropType | Promise<{ default: ImageSourcePropType }>
-
iosSFSymbols7_0
-

Types

IconName

Android
iOS

A platform-specific icon definition.

Pass a primitive (require()'d XML asset on Android, string SF Symbol on iOS) or use Icon.select for a cross-platform definition.

The plain object form ({ ios, android }) is also accepted but does not tree-shake — the Android bundle still includes the iOS asset and vice versa. Prefer Icon.select so the babel-preset-expo plugin can rewrite the call into a Platform.OS ternary that Metro DCE can fold per platform.

Type: SFSymbol or ImageSourcePropType or object shaped as below:

PropertyTypeDescription
androidImageSourcePropType
-
iosSFSymbol
-