Back to Tamagui

Expo Guide

code/tamagui.dev/data/docs/guides/expo.mdx

1.144.45.7 KB
Original Source

We've created a new template repo for starting an Expo Router app based on the Expo starter repo.

<Notice theme="blue"> This template requires Yarn 4.4.0 or greater. You can set yarn to the latest version by running `yarn set version stable`. </Notice>
bash
yarn create tamagui@latest --template expo-router

There are also pre-made community Expo starters.

Install

Use this guide to set up Tamagui with Expo Native and Web.

<Notice theme="blue"> To support dark mode, update your `app.json` to `app.config.ts` and set `userInterfaceStyle` to `"automatic"`. </Notice>

Native

Create a new Expo project:

bash
yarn dlx create-expo-app -t expo-template-blank-typescript
<Notice theme="blue"> This guide assumes Expo is configured with TypeScript support. </Notice>

The following steps are optional but useful for many apps. They enable the optimizing compiler, Reanimated, and support for process.env.XYZ environment variables.

Add @tamagui/babel-plugin:

bash
yarn add @tamagui/babel-plugin

If you have a tamagui.build.ts (recommended — see compiler install docs), no options are needed:

Update your babel.config.js to include the optional @tamagui/babel-plugin:

js
module.exports = function (api) {
  api.cache(true)
  return {
    presets: ['babel-preset-expo'],
    plugins: [
      '@tamagui/babel-plugin',
    ],
  }
}
<Notice> If you're using a monorepo you probably want to use [this Metro configuration](/docs/guides/metro#native). </Notice>

Expo Router / Web

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

tsx
import { defaultConfig } from '@tamagui/config/v5'
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:

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:

bash
npx expo install expo-font

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

<Spacer size="$6" /> <InlineTabs id="font" defaultValue="tamagui"> <InlineTabs.List> <InlineTabs.Tab value="tamagui">Tamagui</InlineTabs.Tab> <InlineTabs.Tab value="expo">Expo Google Fonts</InlineTabs.Tab> </InlineTabs.List>

<InlineTabs.Content value="tamagui"> 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:

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 />
}

</InlineTabs.Content>

<InlineTabs.Content value="expo"> Use the @expo-google-fonts package, a collection of Google Fonts that work with Expo:

<Notice theme="green"> You can find the [full list of fonts](https://github.com/expo/google-fonts/tree/master/font-packages) and usage instructions in the [Expo documentation](https://github.com/expo/google-fonts). </Notice>

Install the font package:

bash
npx expo install @expo-google-fonts/inter

Import the useFonts hook and load the fonts:

tsx
import { useFonts, Inter_400Regular, Inter_900Black } from '@expo-google-fonts/inter'

function App() {
  const [loaded] = useFonts({
    Inter_400Regular,
    Inter_900Black,
  })

  useEffect(() => {
    if (loaded) {
      // can hide splash screen here
    }
  }, [loaded])

  if (!loaded) {
    return null
  }

  return <MyApp />
}

</InlineTabs.Content> </InlineTabs>

<Notice> For more information on loading fonts in Expo, see the [Expo documentation](https://docs.expo.dev/develop/user-interface/fonts/). </Notice>

First time starting Expo

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

bash
npx expo start -c

Your package.json scripts should look something like this:

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"
  }
}