@umituz/react-native-icons
v1.0.9
Published
Package-agnostic icon system for React Native with support for multiple icon providers
Downloads
437
Maintainers
Readme
@umituz/react-native-icons
A package-agnostic icon system for React Native that works with any icon library (lucide-react-native, @expo/vector-icons, ionicons, or custom).
Features
- 🎨 Package-Agnostic: Switch between icon providers without changing your code
- 🔄 Automatic Name Normalization: Works with kebab-case, PascalCase, camelCase, or lowercase
- 📦 Zero Breaking Changes: Includes backward-compatible
iconRendererAPI - 🎯 Type-Safe: Full TypeScript support with strict types
- ⚡ Performant: Built-in caching and name resolution
- 🛡️ Graceful Fallbacks: Automatic fallback icons for missing icons
- 🔌 Extensible: Easy to add custom icon providers
Installation
npm install @umituz/react-native-iconsThen install your preferred icon provider:
# For Lucide icons (recommended)
npm install lucide-react-native
# OR for Expo Vector Icons
npm install @expo/vector-icons
# OR for Ionicons
npm install ioniconsQuick Start
1. Configure the Icon Provider
Wrap your app with the IconProvider:
// App.tsx
import { IconProvider } from '@umituz/react-native-icons';
function App() {
return (
<IconProvider config={{ type: 'lucide' }}>
{/* Your app */}
</IconProvider>
);
}2. Use Icons Anywhere
import { Icon } from '@umituz/react-native-icons';
<Icon name="ArrowLeft" size={24} color="#000" />
<Icon name="heart" size={32} color="red" /> // Legacy names work tooUsage
Basic Icon
import { Icon } from '@umituz/react-native-icons';
<Icon name="User" size={24} color="text" />With Style
<Icon
name="Settings"
size={32}
color="primary"
style={{ marginLeft: 16 }}
/>Different Providers
Lucide Icons (Default)
<IconProvider config={{ type: 'lucide' }}>
<Icon name="Sparkles" size={24} />
</IconProvider>Expo Vector Icons
<IconProvider
config={{
type: 'expo',
expoVectorIcons: {
fontFamily: 'MaterialIcons', // or 'Ionicons', 'FontAwesome', etc.
}
}}
>
<Icon name="star" size={24} />
</IconProvider>Custom Provider
import { IIconProvider } from '@umituz/react-native-icons';
class MyCustomProvider implements IIconProvider {
getIcon(name: string, size: number, color: string) {
// Your custom icon logic
return <MyIcon name={name} size={size} color={color} />;
}
hasIcon(name: string): boolean {
return true;
}
getAvailableIcons(): string[] {
return ['icon1', 'icon2'];
}
}
<IconProvider
config={{
type: 'custom',
customProvider: new MyCustomProvider()
}}
>
<Icon name="icon1" size={24} />
</IconProvider>Backward Compatibility
Migrating from iconConfig.iconRenderer? No problem! Use the iconRenderer export:
// Before (old way)
import { iconConfig } from './core/config/icons/iconConfig';
iconConfig.iconRenderer({ name: 'ArrowLeft', size: 24, color: '#000' });
// After (new way)
import { iconRenderer } from '@umituz/react-native-icons';
iconRenderer({ name: 'ArrowLeft', size: 24, color: '#000' });API Reference
Icon Component
interface IconProps {
name: string; // Icon name (any format)
size?: number; // Size in pixels (default: 24)
color?: string; // Color (default: '#000')
style?: StyleProp<ViewStyle>;
testID?: string;
}IconProvider
interface IconProviderProps {
children: ReactNode;
config?: IconProviderConfig;
provider?: IIconProvider;
}
interface IconProviderConfig {
type: 'lucide' | 'expo' | 'ionicons' | 'custom';
customProvider?: IIconProvider;
expoVectorIcons?: {
fontFamily?: string;
};
}Hooks
useIcon
Hook to get an icon with resolution and fallbacks:
const { icon, resolvedName, isFallback } = useIcon({
name: 'ArrowLeft',
size: 24,
color: '#000'
});
if (isFallback) {
console.warn(`Icon ${resolvedName} not found, using fallback`);
}useIconRegistry
Access the icon registry directly:
const registry = useIconRegistry();
const result = registry.getIcon('ArrowLeft', 24, '#000');Name Normalization
The package automatically converts between different icon name formats:
ArrowLeft→arrow-left→arrowLeft- All resolve to the same icon!
This means you can use whatever format you prefer, or mix and match.
Legacy Icon Support
The package includes legacy mappings from common icon configurations:
// All of these work:
<Icon name="close" />
<Icon name="close-outline" />
<Icon name="X" />
<Icon name="heart" />
<Icon name="Heart" />
<Icon name="arrow-left" />
<Icon name="ArrowLeft" />Migration Guide
From iconConfig.iconRenderer
Step 1: Install the package and provider
npm install @umituz/react-native-icons lucide-react-nativeStep 2: Add IconProvider to your app root
// App.tsx
import { IconProvider } from '@umituz/react-native-icons';
function App() {
return (
<DesignSystemProvider {...config}>
<IconProvider config={{ type: 'lucide' }}>
{/* Your app */}
</IconProvider>
</DesignSystemProvider>
);
}Step 3: Replace iconConfig imports
// Before
import { iconConfig } from '@/core/config/icons/iconConfig';
iconConfig.iconRenderer({ name: 'ArrowLeft', size: 24, color: '#000' });
// After
import { iconRenderer } from '@umituz/react-native-icons';
iconRenderer({ name: 'ArrowLeft', size: 24, color: '#000' });Step 4: (Optional) Use the Icon component for cleaner code
import { Icon } from '@umituz/react-native-icons';
<Icon name="ArrowLeft" size={24} color="#000" />Step 5: Delete old icon files
rm client/core/config/icons/iconConfig.ts
rm client/utils/icons.tsAdvanced Usage
Custom Icon Provider
import { IIconProvider } from '@umituz/react-native-icons';
class CustomIconProvider implements IIconProvider {
getIcon(name: string, size: number, color: string) {
// Load icons from your API, CDN, etc.
const IconComponent = this.loadIconFromAPI(name);
return React.createElement(IconComponent, { size, color });
}
hasIcon(name: string): boolean {
return this.checkIconExists(name);
}
getAvailableIcons(): string[] {
return this.getIconList();
}
}
// Use it
<IconProvider
config={{
type: 'custom',
customProvider: new CustomIconProvider()
}}
>
<App />
</IconProvider>Programmatic Icon Resolution
import { useIconRegistry } from '@umituz/react-native-icons';
function MyComponent() {
const registry = useIconRegistry();
const handleIconCheck = () => {
const result = registry.getIcon('SomeIcon', 24, '#000');
console.log('Resolved name:', result.resolvedName);
console.log('Is fallback:', result.isFallback);
};
return <Button onPress={handleIconCheck}>Check Icon</Button>;
}Cache Management
const registry = useIconRegistry();
// Clear cache
registry.clearCache();
// Get cache stats
const stats = registry.getCacheStats();
console.log('Cache size:', stats.size);License
MIT
Author
Umit Uz [email protected]
