Get Started
API Reference


expo-font allows loading fonts from the web and using them in React Native components. See more detailed usage information in the Fonts guide.

Platform Compatibility

Android DeviceAndroid EmulatoriOS DeviceiOS SimulatorWeb


expo install expo-font

If you're installing this in a bare React Native app, you should also follow these additional installation instructions.

import * as Font from 'expo-font';

const [loaded, error] = useFonts({ ... });
Load a map of fonts with loadAsync. This returns a boolean if the fonts are loaded and ready to use. It also returns an error if something went wrong, to use in development.

  • fonts ({ [fontFamily: string]: FontSource }) -- A map of fontFamilys to FontSources. After loading the font you can use the key in the fontFamily style prop of a Text element.

  • loaded (boolean) -- A boolean to detect if the font for fontFamily has finished loading.
  • error (Error | null) -- An error encountered when loading the fonts.

function App() {
  const [loaded] = useFonts({
    Montserrat: require('./assets/fonts/Montserrat.ttf'),

  if (!loaded) {
    return null;

  return <Text style={{ fontFamily: 'Montserrat' }} />;

Highly efficient method for loading fonts from static or remote resources which can then be used with the platform's native text elements. In the browser this generates a @font-face block in a shared style sheet for fonts. No CSS is needed to use this method.

  • { [fontFamily: string]: FontSource } -- A map of fontFamilys to FontSources. After loading the font you can use the key in the fontFamily style prop of a Text element.

await loadAsync({
  // Load a font `Montserrat` from a static resource
  Montserrat: require('./assets/fonts/Montserrat.ttf'),

  // Any string can be used as the fontFamily name. Here we use an object to provide more control
  'Montserrat-SemiBold': {
    uri: require('./assets/fonts/Montserrat-SemiBold.ttf'),
    fontDisplay: FontDisplay.FALLBACK,

// Use the font with the fontFamily property

return <Text style={{ fontFamily: 'Montserrat' }} />;

Returns a promise that resolves when the font has loaded. Often you may want to wrap the method in a try/catch/finally to ensure the app continues if the font fails to load.

Synchronously detect if the font for fontFamily has finished loading.

true if the the font has fully loaded.

Synchronously detect if the font for fontFamily is still being loaded

true if the the font is still loading.

Sets the font-display for a given typeface. This currently only works on web (support is limited so remember to check the coverage). The default font value on web is FontDisplay.AUTO. Even though setting the fontDisplay does nothing on native platforms, the default behavior emulates FontDisplay.SWAP on flagship devices like iOS, Samsung, Pixel, etc. Default functionality varies on One Plus devices. In the browser this value is set in the generated @font-face CSS block and not as a style property meaning you cannot dynamically change this value based on the element it's used in.
  • AUTO: (Default on web) The font display strategy is defined by the user agent or platform. This generally defaults to the text being invisible until the font is loaded. Good for buttons or banners that require a specific treatment.
  • SWAP: Fallback text is rendered immediately with a default font while the desired font is loaded. This is good for making the content appear to load instantly and is usally preferred.
  • BLOCK: The text will be invisible until the font has loaded. If the font fails to load then nothing will appear - it's best to turn this off when debugging missing text.
  • FALLBACK: Splits the behavior between SWAP and BLOCK. There will be a 100ms timeout where the text with a custom font is invisible, after that the text will either swap to the styled text or it'll show the unstyled text and continue to load the custom font. This is good for buttons that need a custom font but should also be quickly available to screen-readers.
  • OPTIONAL: This works almost identically to FALLBACK, the only difference is that the browser will decide to load the font based on slow connection speed or critical resource demand.
enum FontDisplay {
  AUTO = 'auto',
  BLOCK = 'block',
  SWAP = 'swap',
  FALLBACK = 'fallback',
  OPTIONAL = 'optional',

await loadAsync({
  roboto: {
    uri: require('./roboto.ttf'),
    // Only effects web
    display: FontDisplay.SWAP,

Used to dictate the resource that is loaded into the provided font namespace when used with loadAsync. Optionally on web you can define a display value which sets the font-display property for a given typeface in the browser.
type FontResource = {
  uri: string | number;
  display?: FontDisplay;

The different types of assets you can provide to the loadAsync() function. A font source can be a URI, a module ID, or an Expo Asset.
type FontSource = string | number | Asset | FontResource;

ERR_FONT_APIIf the arguments passed to loadAsync are invalid.
ERR_FONT_SOURCEThe provided resource was of an incorrect type.
ERR_WEB_ENVIRONMENTThe browser's document element doesn't support injecting fonts.
ERR_DOWNLOADFailed to download the provided resource.
ERR_FONT_FAMILYInvalid font family name was provided.
ERR_UNLOADAttempting to unload fonts that haven't finished loading yet.