Last updated on March 24, 2026
Custom Fonts
How to load and use custom fonts with Nativewind v5 and Expo
React Native handles fonts differently from the web. There is no @font-face, no automatic font discovery, and no fallback font stacks. Every font weight is a separate file, and the file name matters. This guide walks through the full setup.
A complete working example is available at nativewind/custom-fonts-example-v5.
Prerequisites
- An Expo project with Nativewind v5 installed
- A custom font you want to use (this guide uses Inter)
Step 1: Choose your font files
Use OTF or TTF format. OTF files render slightly better and have a smaller file size. Either format works across iOS, Android, and web.
Variable fonts do not work on React Native. You must download individual static weight files. For Inter, that means separate files for Regular, Bold, Italic, Medium, etc.
Download the static font files from your font's release page. For Inter, grab the OTF files from the GitHub releases.
Step 2: Name files correctly
Place font files in your project, for example assets/fonts/:
The file name must match the PostScript name of the font. iOS uses the PostScript name to look up fonts at runtime. If the names don't match, the font silently fails to load on iOS while appearing to work on Android.
You can check a font's PostScript name by opening it in Font Book (macOS) or using a tool like fontdrop.info.
Step 3: Load fonts with expo-font
The simplest approach is to use the expo-font config plugin in app.json:
Alternatively, load fonts at runtime with the useFonts hook:
The app.json approach is preferred because fonts are available immediately without a loading state.
Step 4: Verify with inline styles
Before touching your CSS theme, confirm the fonts actually loaded:
If this does not work, the issue is with font loading, not with Nativewind. Check your file names and app.json config.
Step 5: Add to your CSS theme
In v5, fonts are defined in CSS using the @theme directive in your global.css:
Each --font-* variable becomes a font-* utility class automatically.
React Native does not support fallback fonts. The value must be a single font name, not a comma-separated list.
Step 6: Use in components
v5 vs v4
In v4, fonts were configured in JavaScript via tailwind.config.js:
In v5, this moves to CSS, which is simpler and consistent with how Tailwind CSS v4 works:
The usage in components (className="font-inter") is identical in both versions.
Common pitfalls
| Problem | Cause | Fix |
|---|---|---|
| Font works on Android but not iOS | File name doesn't match PostScript name | Rename the file to match exactly |
| Font doesn't render at all | Font not loaded by expo-font | Check app.json plugin config or useFonts hook |
Using font-bold doesn't make Inter bold | font-bold sets fontWeight, not fontFamily | Use font-inter-bold to set the bold font family |
| Variable font doesn't work | React Native doesn't support variable fonts | Download static weight files instead |
| Font renders as system default | PostScript name mismatch | Open font in Font Book and verify the PostScript name |
Platform-specific fonts
Use the ios: and android: variants for platform-specific font overrides:
Or override the default system fonts in your theme:
This makes font-sans (the default) use Inter instead of the system font.