Building cross-platform mobile applications often slows down when you spend hours searching for consistent, scalable vector icons. By combining Expo with Ionicons, you can add thousands of production-ready icons to your React Native project in minutes without bloating your app bundle.
This guide walks through setting up Ionicons in an Expo project, managing vector assets efficiently, and avoiding common pitfalls like broken imports or slow render times.
Understanding Ionicons and Expo
Expo provides a managed workflow that abstracts native configuration files, letting you build iOS and Android apps using JavaScript and TypeScript. Instead of dealing with CocoaPods or Gradle for every new dependency, Expo bundles a vetted library of native modules known as expo-modules.
Ionicons is an open-source icon set built specifically for web, desktop, and mobile applications. When paired with Expo, Ionicons doesn't require separate font linking steps because Expo's vector icons package already includes Ionicons out of the box.
Why Use This Stack
Managing raw SVG files or separate font files manually drains development time. Using Ionicons inside an Expo environment gives you several direct advantages:
- Zero native linking: Expo handles asset bundling automatically across iOS, Android, and web targets.
- Vector scalability: Icons render crisply on high-density Retina displays and lower-resolution screens alike.
- Extensive variety: Access over 1,300 distinct glyphs spanning outline, sharp, and filled variants.
- Cross-platform consistency: Your UI elements look identical on both iPhone and Android devices.
Setting Up Ionicons in an Expo Project
Setting up vector icons in an existing or fresh Expo project takes only a few terminal commands. You don't need to install external packages like react-native-vector-icons manually because @expo/vector-icons comes pre-installed in standard Expo templates.
Step 1: Verify Your Dependencies
Open your project's package.json file and check if @expo/vector-icons is listed under dependencies. If you started your app using npx create-expo-app, it's already there. If it's missing, install it via your terminal:
npx expo install @expo/vector-icons
Using npx expo install ensures you get the exact version compatible with your current Expo SDK version, preventing runtime crashes caused by mismatched native modules.
Step 2: Import and Render an Icon
To display an icon inside any component, import Ionicons from @expo/vector-icons. Pass the icon name, size, and color as props.
import React from 'react';
import { StyleSheet, View } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
export default function HomeScreen() {
return (
<View style={styles.container}>
<Ionicons name="home-outline" size={32} color="#007AFF" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
Make sure you check the official Ionicons website to find exact glyph names. For example, outline variants use the -outline suffix, while filled variants use no suffix or -sharp for sharp-edged design aesthetics.
Advanced Usage and Customization
Hardcoding icon sizes and colors directly inside your component tree quickly leads to messy codebases. To build a maintainable UI, you'll want to structure your icon usage cleanly.
Creating a Reusable Icon Component
If your app uses specific icon styling across multiple screens, wrap Ionicons in a custom wrapper component. This keeps your color palette and sizing consistent.
import React from 'react';
import { Ionicons } from '@expo/vector-icons';
type AppIconProps = {
name: keyof typeof Ionicons.glyphMap;
size?: number;
color?: string;
};
export function AppIcon({ name, size = 24, color = '#333333' }: AppIconProps) {
return <Ionicons name={name} size={size} color={color} />;
}
TypeScript will automatically validate your icon names against the full Ionicons glyph map, preventing typos before you even run your build.
Handling Dynamic States
Icons often change appearance based on user interaction, such as toggling a favorite button or switching tabs. Manage these states using standard React hooks.
import React, { useState } from 'react';
import { TouchableOpacity } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
export function FavoriteButton() {
const [isLiked, setIsLiked] = useState(false);
return (
<TouchableOpacity onPress={() => setIsLiked(!isLiked)}>
<Ionicons
name={isLiked ? 'heart' : 'heart-outline'}
size={28}
color={isLiked ? '#FF3B30' : '#8E8E93'}
/>
</TouchableOpacity>
);
}はん
Common Mistakes to Avoid
Even though Expo and Ionicons integrate smoothly, developers often run into a few common pitfalls during development.
- Forgetting the Expo SDK version match: Installing vector packages with plain
npm installinstead ofnpx expo installfrequently breaks dependency trees when upgrading SDKs. - Using web-only icon names: Ionicons supports web-specific classes that don't always map cleanly to React Native vector font glyph maps. Always reference the mobile glyph list.
- Nesting icons inside text incorrectly: While React Native allows nesting icons inside
<Text>components, improper line-height configurations can vertically misalign your icons. ApplytextAlignVerticalor wrap them in flex containers when necessary. - Ignoring accessibility labels: Screen readers won't know what an icon represents unless you provide an
accessibilityLabelprop on the parent touchable or view container.
Frequently Asked Questions
Do I need to link native fonts manually when using Expo?
No. Expo automatically bundles vector font files like Ionicons, FontAwesome, and MaterialIcons during the build process. You don't need to configure react-native.config.js or run link commands.
Can I use custom SVG files alongside Ionicons in Expo?
Yes. If you need SVGs that aren't available in Ionicons, install react-native-svg and react-native-svg-transformer to render custom vector graphics directly.
Why is my icon showing up as a blank box or question mark?
This usually happens when the font asset fails to load asynchronously before the component renders. Ensure you are using @expo/vector-icons, which handles font loading automatically in managed Expo apps.
How do I check all available icon names?
You can browse the complete directory directly on the Ionicons website, where clicking any icon copies its exact React Native identifier to your clipboard.