Integrations
React Native
Best Practices with React Native

Best Practices with React Native

This guide collects practical recommendations for using Hugeicons in React Native so your icons stay fast, consistent, and accessible.

Import icons efficiently

Always import only the icons you need from the specific package:

import React from 'react'
import { HugeiconsIcon } from '@hugeicons/react-native'
import { Notification03Icon } from '@hugeicons/core-free-icons'
// or, for Pro:
// import { Notification03Icon } from '@hugeicons-pro/core-stroke-rounded'
 
export function Example() {
  return <HugeiconsIcon icon={Notification03Icon} />
}

Avoid wildcard imports (e.g. import * as Icons from '...') because they prevent bundlers from tree‑shaking unused icons and can increase your bundle size.

Keep icons accessible

Use different patterns for decorative vs meaningful icons:

  • Decorative icons (purely visual): render them inside components that already have accessible labels (e.g., Text or Pressable with accessibilityLabel).
  • Meaningful icons (e.g., trash, download): make sure there is a label via visible text or accessibilityLabel.
import React from 'react'
import { Pressable, Text } from 'react-native'
import { HugeiconsIcon } from '@hugeicons/react-native'
import { DownloadIcon, Delete01Icon } from '@hugeicons/core-free-icons'
 
export function AccessibleButtons() {
  return (
    <>
      {/* Icon with visible label (screen readers read the text) */}
      <Pressable>
        <HugeiconsIcon icon={DownloadIcon} size={18} />
        <Text>Download</Text>
      </Pressable>
 
      {/* Icon-only button with accessibilityLabel */}
      <Pressable accessibilityLabel="Delete">
        <HugeiconsIcon icon={Delete01Icon} size={18} />
      </Pressable>
    </>
  )
}

Avoid relying on icon shape alone to convey critical information; pair icons with text or accessible labels where possible. On each platform, accessibilityLabel ties into the native accessibility APIs (like VoiceOver and TalkBack), so your icon buttons remain usable for screen‑reader users.

Use altIcon + showAlt for state

Instead of conditionally rendering two separate icons, use altIcon and showAlt on the same HugeiconsIcon:

import React, { useState } from 'react'
import { Pressable } from 'react-native'
import { HugeiconsIcon } from '@hugeicons/react-native'
import { ViewIcon, ViewOffSlashIcon } from '@hugeicons-pro/core-stroke-rounded'
 
export function PasswordToggle() {
  const [visible, setVisible] = useState(false)
 
  return (
    <Pressable
      onPress={() => setVisible(!visible)}
      accessibilityLabel={visible ? 'Hide password' : 'Show password'}
    >
      <HugeiconsIcon
        icon={ViewIcon}
        altIcon={ViewOffSlashIcon}
        showAlt={visible}
        size={18}
      />
    </Pressable>
  )
}

This keeps your JSX simpler and ensures both states share the same sizing and styling.

Create an app-level Icon wrapper

In many apps it’s helpful to create your own Icon component that forwards props to HugeiconsIcon while enforcing project-wide defaults for size, color, and stroke width.

// Icon.tsx
import React from 'react'
import { StyleProp, ViewStyle } from 'react-native'
import { HugeiconsIcon } from '@hugeicons/react-native'
 
type IconProps = {
  icon: unknown
  altIcon?: unknown
  showAlt?: boolean
  size?: number
  color?: string
  strokeWidth?: number
  style?: StyleProp<ViewStyle>
}
 
export function Icon({
  size = 16,
  color = 'black',
  strokeWidth = 1.5,
  ...rest
}: IconProps) {
  return (
    <HugeiconsIcon
      size={size}
      color={color}
      strokeWidth={strokeWidth}
      {...rest}
    />
  )
}

Now you can use Icon throughout your project and adjust defaults (size, color, stroke width, theming) in one place without touching all call sites.

import React from 'react'
import { Pressable } from 'react-native'
import { Icon } from './Icon'
import { Delete01Icon } from '@hugeicons/core-free-icons'
 
export function DeleteButton() {
  return (
    <Pressable accessibilityLabel="Delete">
      <Icon icon={Delete01Icon} size={18} />
    </Pressable>
  )
}

Centralizing patterns like this keeps styling and accessibility consistent across your app.

Plan for dark mode and themes

When supporting dark mode, prefer theme-aware colors instead of hard‑coding colors:

import React from 'react'
import { View } from 'react-native'
import { HugeiconsIcon } from '@hugeicons/react-native'
import { Moon02Icon } from '@hugeicons/core-free-icons'
 
export function DarkModeIcon({ color = '#e5e7eb' }) {
  return (
    <View>
      <HugeiconsIcon
        icon={Moon02Icon}
        size={20}
        color={color}
      />
    </View>
  )
}

If you need different styles per theme (e.g., duotone in dark mode), you can pair altIcon with your theme state (from react-native Appearance API or a theming library).

Name and organize icons consistently

  • Use the shorter *Icon names (SearchIcon) for readability.
  • Use style-specific names (SearchStrokeRounded) only when you need multiple styles of the same icon in one file.
  • Group icons by domain in your codebase (e.g., icons/navigation.ts, icons/forms.ts) to make reuse easier.
// icons/navigation.ts
export { HomeIcon, SearchIcon, Notification03Icon, UserIcon } from '@hugeicons/core-free-icons'

Then import from your own modules instead of raw packages in components to keep imports tidy and consistent.