Fonts
How to add custom fonts to your app.
Caracal ships with the Inter family from @expo-google-fonts/inter, loaded at runtime in src/app/_layout.tsx:
import { Inter_400Regular } from '@expo-google-fonts/inter/400Regular';
import { Inter_500Medium } from '@expo-google-fonts/inter/500Medium';
import { Inter_600SemiBold } from '@expo-google-fonts/inter/600SemiBold';
import { Inter_700Bold } from '@expo-google-fonts/inter/700Bold';
import { useFonts } from 'expo-font';
export default function RootLayout() {
const [loaded] = useFonts({
Inter_400Regular,
Inter_500Medium,
Inter_600SemiBold,
Inter_700Bold,
});
if (!loaded) {
return null;
}
// ...
}The app renders nothing until loaded is true, which keeps text from flashing in a fallback face.
Import each weight by its subpath, and take useFonts from expo-font rather
than from the font package. The package barrel re-exports every weight and italic
the family ships — 18 files for Inter — and all of them are linked into the native
build, because React Native resolves fonts by name at runtime and no bundler or
shrinker can prove the unused ones dead. An ESLint rule enforces this.
Adding another Google Font
Install the family and swap the imports above:
pnpm add @expo-google-fonts/robotoimport { Roboto_400Regular } from '@expo-google-fonts/roboto/400Regular';No prebuild is needed — these packages ship the font files as JS assets.
Adding a local font file
For a font that is not on Google Fonts, create an assets/fonts folder (the starter has none, since Inter ships as a package), put the file in it, and register it with the expo-font config plugin. Caracal already lists the plugin in app.config.ts; add a fonts array to it:
import type { ConfigContext, ExpoConfig } from '@expo/config';
export default ({ config }: ConfigContext): ExpoConfig => ({
...config,
plugins: [
[
'expo-font',
{
fonts: ['./assets/fonts/SpaceGrotesk-Regular.ttf'],
},
],
],
});This links the font natively, so you need to run pnpm prebuild and then pnpm ios or pnpm android before the font is available. A local font added this way does not need useFonts.
Using the font in your components
Font families are theme tokens, set in src/themes/sky.css — not in a tailwind.config.js. Update the --font-* variables in both the @variant light and @variant dark blocks:
@layer theme {
:root {
@variant light {
--font-normal: "Inter_400Regular";
--font-medium: "Inter_500Medium";
--font-semibold: "Inter_600SemiBold";
--font-bold: "Inter_700Bold";
/* ... */
}
}
}The value must match the name the font is registered under — the export name for @expo-google-fonts packages, or the file's PostScript name for a local file. These tokens back the font-normal, font-medium, font-semibold, and font-bold class names, and HeroUI Native components read them too:
<Text className="font-bold text-lg">Hello</Text>More details can be found in the Uniwind documentation and the expo-font docs.