Skip to main content
ExpoTutorials
Malik Chohra

By Malik Chohra

Add Custom Fonts in Expo (2026 Guide)

Complete guide for implementing custom fonts in Expo apps using expo-font and Google Fonts. Includes async loading, theme integration, and performance tips.

Professional Font Management in Expo

Typography plays a crucial role in creating polished mobile applications. Custom fonts help establish brand identity and improve user experience. With Expo SDK 53, implementing custom fonts has become more straightforward while maintaining excellent performance and developer experience.

This comprehensive guide covers everything you need to know about adding custom fonts to your Expo app, from basic implementation to advanced optimization techniques.

Using expo-font

The expo-font package provides a simple API for loading custom fonts asynchronously. This ensures your app doesn't block while fonts are loading, maintaining smooth app startup performance.

// app/_layout.tsx
import { useFonts } from 'expo-font';
import * as SplashScreen from 'expo-splash-screen';

SplashScreen.preventAutoHideAsync();

export default function RootLayout() {
  const [fontsLoaded] = useFonts({
    'Inter-Regular': require('./assets/fonts/Inter-Regular.ttf'),
    'Inter-Bold': require('./assets/fonts/Inter-Bold.ttf'),
    'Inter-SemiBold': require('./assets/fonts/Inter-SemiBold.ttf'),
  });

  useEffect(() => {
    if (fontsLoaded) {
      SplashScreen.hideAsync();
    }
  }, [fontsLoaded]);

  if (!fontsLoaded) return null;

  return <Stack />;
}

Google Fonts Integration

Expo provides seamless Google Fonts integration through the @expo-google-fonts packages. This eliminates the need to download and manage font files manually.

// Install Google Fonts
npx expo install expo-font @expo-google-fonts/inter

// Usage
import { useFonts, Inter_400Regular, Inter_700Bold } from '@expo-google-fonts/inter';

const [fontsLoaded] = useFonts({
  Inter_400Regular,
  Inter_700Bold,
});

Local TTF Font Integration

For custom brand fonts or fonts not available through Google Fonts, use local TTF or OTF files. Drop them into an assets/fonts directory and reference them with require. For production builds you can also preload them via the Expo config so they're embedded in the native bundle rather than fetched at runtime:

// app.json
{
  "expo": {
    "plugins": [
      [
        "expo-font",
        { "fonts": ["./assets/fonts/Inter-Regular.ttf", "./assets/fonts/Inter-Bold.ttf"] }
      ]
    ]
  }
}
  • Directory structure - Keep every weight in assets/fonts/ so the config plugin and your useFonts call stay in sync.
  • Font variants - Bundle only the weights you actually render (Regular, SemiBold, Bold is enough for most apps).
  • Naming convention - Match the registered family name exactly to what you reference in styles, 'Inter-Bold', not 'Inter Bold'.

Theme System Integration

Integrate your custom fonts with your theme system (like Restyle) for consistent typography throughout your application.

// theme.ts
const theme = createTheme({
  textVariants: {
    header: {
      fontFamily: 'Inter-Bold',
      fontSize: 34,
      lineHeight: 42,
    },
    body: {
      fontFamily: 'Inter-Regular',
      fontSize: 16,
      lineHeight: 24,
    },
  },
});

Performance Optimization

Follow these optimization techniques to ensure fast font loading and smooth app performance:

  • Subset Fonts - Include only the characters you need
  • Async Loading - Always load fonts asynchronously
  • Splash Screen - Keep splash screen visible until fonts load
  • Font Variants - Only include weights you actually use

Common Issues and Solutions

A handful of problems account for nearly every font bug in Expo:

  • Font not showing up - The family name in your style doesn't match the key you registered in useFonts. They must be identical, including case.
  • Bold/italic ignored - React Native does not synthesize weights for custom fonts. Load a separate file for each weight and reference it explicitly with fontFamily rather than fontWeight.
  • Flash of unstyled text - Keep the splash screen up until fontsLoaded is true (as shown above) so the first paint already uses your font.
  • Font missing after build - In bare or EAS builds, register fonts through the expo-font config plugin so they're embedded natively instead of relying on runtime loading.

Build Professional Mobile Apps

For Developers: AI Mobile Launcher includes pre-configured custom font loading with Google Fonts integration and Restyle theme support.

For Founders: Need a mobile app with beautiful typography? Contact AI Mobile Launcher for professional development.