How to Use Local Fonts in React Native (Expo + expo-router)

If you’re building a beautiful React Native app and want to spice up your UI with some custom fonts, you’re in the right place! In this post, I’ll walk you through how to use local fonts in a React Native project using Expo and expo-router.

Let’s get started step by step β€” and by the end, you’ll have clean typography running in your app. πŸ’…

🎯 Why Use Local Fonts?

Using local fonts gives you:

  • Full control over typography

  • A unique visual identity

  • No dependency on Google Fonts or external APIs

  • Offline availability πŸš€

Step 1: Add Fonts to Your Project

Create a fonts folder inside your assets directory and drop in your .ttf or .otf font files.

project-root/
β”œβ”€β”€ assets/
β”‚   └── fonts/
β”‚       β”œβ”€β”€ Sora-Regular.ttf
β”‚       β”œβ”€β”€ Sora-Bold.ttf
β”‚       β”œβ”€β”€ Sora-Light.ttf
β”‚       └── Sora-SemiBold.ttf

 

Step 2: Load Fonts in Your Root Layout

If you’re using expo-router, the perfect place to load your fonts is inside app/_layout.js or app/_layout.tsx (depending on your setup).

import { Stack } from "expo-router";
import { useFonts } from "expo-font";
import { SplashScreen } from "expo-router";
import { useEffect } from "react";

export default function RootLayout() {
  const [loaded] = useFonts({
    "Sora-Regular": require("../assets/fonts/Sora-Regular.ttf"),
    "Sora-Bold": require("../assets/fonts/Sora-Bold.ttf"),
    "Sora-Light": require("../assets/fonts/Sora-Light.ttf"),
    "Sora-SemiBold": require("../assets/fonts/Sora-SemiBold.ttf"),
  });

  useEffect(() => {
    if (loaded) {
      SplashScreen.hideAsync(); // Hide the splash once fonts are ready
    }
  }, [loaded]);

  if (!loaded) {
    return null; // Wait till fonts are loaded before rendering anything
  }

  return <Stack />; // Continue rendering the app
}

What’s Happening Here?

  • useFonts: From expo-font, loads fonts asynchronously.

  • SplashScreen.hideAsync(): Ensures the splash screen stays visible until the fonts are fully loaded, preventing layout shift.

  • return null: Freezes UI rendering until fonts are ready.

Step 3: Use the Fonts in Your App

<Text style={{ fontFamily: "Sora-Bold", fontSize: 20 }}>
  Hello Custom Font!
</Text>