Expo Guide

How to set up Tamagui with Expo

Set up Tamagui in an Expo project that targets iOS, Android, and web.

Install

To support dark mode, update your app.json to app.config.ts and set userInterfaceStyle to "automatic".

Native

Create a new Expo project:

yarn dlx create-expo-app -t expo-template-blank-typescript

This guide assumes Expo is configured with TypeScript support.

The following steps enable the optimizing compiler while preserving your existing Expo Babel configuration.

Add @tamagui/cli, which carries the Metro plugin along with the CLI and the other bundler integrations:

yarn add -D @tamagui/cli

If Metro is the only bundler this project will ever use, yarn add @tamagui/metro-plugin on its own is a smaller install and exports exactly the same things.

Wrap the Expo Metro config with withTamagui. If you have a tamagui.build.ts (recommended; see compiler install docs), no options are needed. Otherwise, pass them inline:

metro.config.js

const { getDefaultConfig } = require('expo/metro-config')
const { withTamagui } = require('@tamagui/cli/metro')
module.exports = withTamagui(getDefaultConfig(__dirname), {
components: ['tamagui'],
config: './tamagui.config.ts',
})

If you’re using a monorepo, see the Metro guide.

Expo Router / Web

Add @tamagui/config and tamagui to your package.json and install them. Then create a tamagui.config.ts:

tamagui.config.ts

import { defaultConfig } from '@tamagui/config/v6'
import { createTamagui } from 'tamagui'
export const tamaguiConfig = createTamagui(defaultConfig)
export default tamaguiConfig
export type Conf = typeof tamaguiConfig
declare module 'tamagui' {
interface TamaguiCustomConfig extends Conf {}
}

Then update app/_layout.tsx:

app/_layout.tsx

import '../tamagui.generated.css'
import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native'
import { Stack } from 'expo-router'
import { useColorScheme } from 'react-native'
import { TamaguiProvider } from 'tamagui'
import { tamaguiConfig } from '../tamagui.config'
export default function RootLayout() {
const colorScheme = useColorScheme()
return (
// add this
<TamaguiProvider config={tamaguiConfig} defaultTheme={colorScheme!}>
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
<Stack>
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
<Stack.Screen name="modal" options={{ presentation: 'modal' }} />
</Stack>
</ThemeProvider>
</TamaguiProvider>
)
}

Setup Tamagui

From here on out you can follow the Installation and Configuration docs.

Loading fonts

Install the expo-font package:

yarn dlx expo install expo-font

Load your fonts so React Native can recognize them. There are several ways to do this:

Use the @tamagui/font-inter package, a pre-configured version of the Inter font that works with Tamagui:

Import the useFonts hook and load the fonts:

App.tsx

import { useFonts } from 'expo-font'
function App() {
const [loaded] = useFonts({
Inter: require('@tamagui/font-inter/otf/Inter-Medium.otf'),
InterBold: require('@tamagui/font-inter/otf/Inter-Bold.otf'),
})
useEffect(() => {
if (loaded) {
// can hide splash screen here
}
}, [loaded])
if (!loaded) {
return null
}
return <MyApp />
}

For more information on loading fonts in Expo, see the Expo documentation.

First time starting Expo

The first time running your project with Tamagui, be sure to clear the cache:

yarn dlx expo start -c

Your package.json scripts should look something like this:

package.json

{ "scripts": { "start-native": "expo start -c", "start-web": "expo start -c", "android": "yarn expo run:android", "ios": "yarn expo run:ios", "web": "expo start --web" } }