Clayton Francis Entrepreneur, software developer, and avid learner. Let’s share the knowledge!

react-native-vector-icons: Icons and fonts for React Native apps

7 min read 1979

Icons Fonts React Native Apps React Native Vector Icons

Editor’s note: This article was updated on 3 May 2022 to reflect the most recent information regarding react-native-vector-icons, including a quick fix for an auto-linking error that sometimes occurs in iOS.

When it comes to UI/UX, fonts and icons matter. Icons serve as a visual aid for users to navigate your app, and your choice of font (and font color) sets the tone for your app or brand.

Let’s be real: you’d be unlikely to purchase life insurance from a company that uses a cartoonish font such as Alloy Ink or Vegan Style in its contracts. And I couldn’t imagine an app without any icons. Seriously, if you know of one in the App Store, drop me a comment with a link — I’m curious!

In this React Native tutorial, we’ll show you how to:

The full source code associated with this demo is available on GitHub.

Jump ahead:

Creating a React Native project

To initialize a React Native project, paste the following into your terminal:

npx react-native init yourAppNameHere --template react-native-template-typescript && cd yourAppNameHere

This will create a new React Native project with a TypeScript template. Navigate to the project folder.

The next step is to build our app for each OS. First, iOS:

yarn run ios 

Now, for Android:

yarn run android

Linking and unlinking with React Native Asset

As software developers, anything that improves our workflow is a welcome change. React Native Asset makes linking and unlinking more straightforward than using react-native link.

First, install react-native-asset globally:

yarn global add react-native-asset

In your project folder, create a new folder called assets, then create another folder inside it called fonts. Or you can use the terminal:

mkdir -p assets/fonts

Head over to Google Fonts to download a font family. For this example, we’re going with Nunito, but feel free to diverge with a font of your choice.

Once you’ve downloaded the file, unzip it and add your chosen font weights to the fonts folder:

Nunito In Google Fonts

Now, create a new file in your project folder called react-native.config.js:

touch react-native.config.js

Then, add the following:

module.exports = {
  assets: ['./assets/fonts'],
};

Finally, use React Native Asset to link the font files. Type the following in your terminal:

react-native-asset

If you need to remove and unlink a font, simply delete it from the fonts folder, then run react-native-asset again. Simple as that.

Creating a text component in React Native

Let’s create a custom text component to consume our new fonts. Create a folder called components with a file inside called Text.tsx, then add the following code:

import React from 'react';
import {
  Text as ReactText,
  StyleSheet,
  StyleProp,
  TextStyle,
} from 'react-native';

type TextProps = {
  children: React.ReactNode;
  style?: StyleProp<TextStyle>;
};

export const Text = ({style, children}: TextProps) => {
  return <ReactText style={[styles.font, style]}>{children}</ReactText>;
};

const styles = StyleSheet.create({
  font: {
    fontFamily: 'Nunito-Regular',
  },
});

The above code creates a Text component with a font-family of Nunito and a regular font-weight that we can use across our app. We get the children and style types (TextProps) from React Native.

Now that we have our Text component, let’s use it!

Replace your App.tsx file with the following:

import React from 'react';
import {SafeAreaView, StyleSheet, StatusBar} from 'react-native';
import {Text} from './components/Text';

const App = () => {
  return (
    <>
      <StatusBar barStyle="dark-content" />
      <SafeAreaView style={styles.container}>
        <Text>This font-weight is 'regular' </Text>
        <Text style={styles.boldFont}>This font-weight is 'bold' </Text>
      </SafeAreaView>
    </>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  boldFont: {
    fontFamily: 'Nunito-Bold',
  },
});

export default App;

Notice that we have two different font-weights. Our Text component on line 11 has a bold font-weight. To achieve this, override the font-weight settings with a bold font using StyleSheet.create (line 23), then pass the value to the style prop in the Text component.

React Native Font-Weight Example

React Native Vector Icons

With over 3,000 free icons and 15.7k GitHub stars, React Native Vector Icons is an excellent choice for all your icon needs. Many popular UI libraries, such as Magnus UI, React Native Paper, and React Native Elements, use React Native Vector Icons, so you’re in good company! And if you don’t find what you’re looking for, you can even make your own icons.

To use this package you need to install it. Head over to your terminal and type:

yarn add react-native-vector-icons && yarn add -D @types/react-native-vector-icons

Installing react-native-vector-icons for iOS

Install the React Native Vecor Icons library and dev dependency in iOS, like so:

cd ios && pod install && cd .. && yarn run ios

Next, navigate to your iOS folder, install your project’s CocoaPods, then navigate back to your project folder.

Troubleshooting auto-linking or updating errors with iOS

If you happen to run into trouble with auto-linking or updating errors while installing React Native Vector Icons on iOS, here’s a neat little trick to fix the issue. Run:

yarn react-native link react-native-vector-icons && yarn react-native unlink react-native-vector-icons && yarn ios

Installing react-native-vector-icons for Android

Install the React Native Vecor Icons library and dev dependency on Android by opening android/app/build.gradle (not android/build.gradle) and adding this import statement:

import org.apache.tools.ant.taskdefs.condition.Os

Installing React Native Vector Icons Android

Then, run the following command in the terminal:

yarn run android

Building an icon component in React Native

Now we’re going to build a reusable icon component.

In your components folder, create a new file called Icon.tsx:

cd components && touch Icon.tsx && cd ..

Then, add the following code:

import React from 'react';
import MIcon from 'react-native-vector-icons/MaterialCommunityIcons';

MIcon.loadFont();

type IconSizeProps = {
  iconSizes: keyof typeof IconSizes;
};

export interface IconProps {
  size: IconSizeProps['iconSizes'];
  name: string;
  color: string;
}

export const IconSizes = {
  small: 13,
  medium: 18,
  large: 23,
  extraLarge: 27,
};

export const MaterialIcon = ({size, name, color}: IconProps) => (
  <MIcon name={name} size={IconSizes[size]} color={color} />
);

For each icon bundle you want to use, import and load it as we have in line 2 (import Material Community Icons bundle set) and line 4 (load the icon bundle).

Loading the icons this way eliminates the need to add any native code to use them.
We can export the components with three props that allow us to control the color, size, and type of icon:

  • size is predefined by IconSizes
  • name defines the icon type
  • color defines the icon color

If you’re new to TypeScript and you’re wondering what’s happening on line 7 and 11, hover over iconSizes and you’ll see this:

React Native TypeScript IconSizes Example

keyof

In TypeScript, you can create types from JavaScript values. The [[keyof]](https://www.typescriptlang.org/docs/handbook/2/keyof-types.html)operator takes an object type (IconSizes on line 16) and returns a string or literal union of its keys:

iconSizes: string | number | symbol

typeof

TypeScript’s version of [typeof](https://www.typescriptlang.org/docs/handbook/2/typeof-types.html) returns the types of the value of an object:

 iconSizes: {
    small: number;
    medium: number;
    large: number;
    extraLarge: number;
}

keyof typeof

keyof typeof indexes the keys of the object and returns a union of literal types:

iconSizes: "small" | "medium" | "large" | "extraLarge"

Now, thanks to the power of TypeScript, every time you use the size prop, your IDE will know what value should be provided and will display the options for you. To access autocomplete in VS Code on Mac, press ctrl and the spacebar simultaneously.



Enabling Autocomplete VS Code

Let’s head back over to App.tsx to test our new Icon component.

import React from 'react';
import {SafeAreaView, StyleSheet, StatusBar} from 'react-native';
import {Text} from './components/Text';
// Import our icon component
import {MaterialIcon} from './components/Icon';

const App = () => {
  return (
    <>
      <StatusBar barStyle="dark-content" />
      <SafeAreaView style={styles.container}>
        <Text>This font-weight is 'regular' </Text>
        <Text style={styles.boldFont}>This font-weight is 'bold' </Text>
        {/* Add icons here */}
        <MaterialIcon size="large" color="purple" name="home" />
        <MaterialIcon size="extraLarge" color="black" name="github" />
      </SafeAreaView>
    </>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  boldFont: {
    fontFamily: 'Nunito-Bold',
  },
});

export default App;

For demonstration purposes, I’ve added a home icon and the GitHub logo below the text with different sizes and colors.

React Native Example App With Icons

Creating an icon button component in React Native

Buttons look great with icons, so let’s make one. For our button component, we’ll use the custom font that we built earlier with a new icon bundle.

In your components folder, create a new file called IconButton.tsx:

cd components && touch IconButton.tsx && cd ..

Add the following code:

import React from 'react';
import FontAwesomeIcon from 'react-native-vector-icons/FontAwesome';
import {Text} from './Text';
import {IconSizes, IconProps} from './Icon';

FontAwesomeIcon.loadFont();

type IconButtonProps = IconProps & {
  text: string;
  onPress: () => void;
};

export const IconButton = ({
  onPress,
  size,
  name,
  color,
  text,
}: IconButtonProps) => (
  <FontAwesomeIcon.Button
    onPress={onPress}
    name={name}
    size={IconSizes[size]}
    color={color}>
    <Text>{text}</Text>
  </FontAwesomeIcon.Button>
);

If we want to use an icon from Material-UI Community Icons, we can import and use the icon component we built already. But this time, we’re going with Font Awesome’s icon bundle set, so we need to load the new icon bundle (line 6).

Now, let’s import our IconButton into App.tsx:

import React from 'react';
import {SafeAreaView, StyleSheet, StatusBar} from 'react-native';
import {Text} from './components/Text';
// Import our icon component
import {MaterialIcon} from './components/Icon';
// Import our icon button component
import { IconButton } from './components/IconButton';

const App = () => {
  return (
    <>
      <StatusBar barStyle="dark-content" />
      <SafeAreaView style={styles.container}>
        <Text>This font-weight is 'regular' </Text>
        <Text style={styles.boldFont}>This font-weight is 'bold' </Text>
        {/* Add icons here */}
        <MaterialIcon size="large" color="purple" name="home" />
        <MaterialIcon size="extraLarge" color="black" name="github" />
        {/* Add icon button here */}
          <IconButton
          onPress={() => {}}
          color="white"
          size="extraLarge"
          name="facebook"
          text="Login in with Facebook"
        />
      </SafeAreaView>
    </>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  boldFont: {
    fontFamily: 'Nunito-Bold',
  },
});

export default App;

As with the MaterialIcon component we built earlier, you can set the color, size, and icon type with the provided props.

React Native Icon Component Example

Conclusion

In this article, we demonstrated how to add icons and fonts to your iOS or Android app. We also reviewed how to use the react-native-vector-icons library and shared how to troubleshoot an iOS auto-linking error.

It’s worth perusing the icons at the design stage of your app; there are some real gems in the icon bundle sets. If you’re looking for something specific, you should try lots of similar, descriptive keywords. For example, a search for “settings” will return a cog icon, but if you want an icon with multiple cogs, try searching “cogs.”

React Native Icon Search

React Native Icon search.

Now that you know how to customize your font, don’t be afraid to extend your text component with a nice font pairing — e.g., Nunito for headers and Roboto for paragraphs:

React Native Example App With Nunito And Roboto Fonts

There you have it! You can customize your fonts and add icons to your heart’s content. Now go forth and build something amazing — just don’t use Vegan Style if you’re selling life insurance!

LogRocket: Instantly recreate issues in your React Native apps.

LogRocket is a React Native monitoring solution that helps you reproduce issues instantly, prioritize bugs, and understand performance in your React Native apps.

LogRocket also helps you increase conversion rates and product usage by showing you exactly how users are interacting with your app. LogRocket's product analytics features surface the reasons why users don't complete a particular flow or don't adopt a new feature.

Start proactively monitoring your React Native apps — .

Clayton Francis Entrepreneur, software developer, and avid learner. Let’s share the knowledge!

Leave a Reply