12 Nov 2026 · 6 min read

Tamagui in Expo: setup, styling and themes

Tamagui in Expo: install it with one command, style with styled() and $tokens, set light and dark themes, and see what runs in Expo Go.

Tamagui is a UI kit, a styling engine and an optimising compiler for React Native and the web. You style components with props and typed variants instead of class strings, and in a production build the compiler resolves the static parts ahead of time. This post covers how Tamagui fits an Expo app, what runs in Expo Go, and how the Tamagui kit in ReadyNative is wired, so you can decide whether it is the styling layer you want.

From tokens to a screenThe tokens file feeds the generated Tamagui config through gen:theme. TamaguiProvider loads that config at the root. Screens use the kit's primitives and styled components with token values.src/theme/tokens.tscolour, space, radiustamagui.config.tsbun run gen:themeTamaguiProviderloads the config at the root@/components/uiBox, Button, Textyour screensstyled + $token valuesDevelopment uses runtime styles; production builds run the compiler.

What Tamagui is made of

Tamagui's docs describe three parts: a fully featured UI kit, a styling engine, and an optimising compiler. The engine gives every component the same style props and $token values. The compiler is optional. It analyses your JSX and styled definitions, resolves what it can at build time, and lowers eligible components to plain React Native views on native.

Tamagui recommends setting up the compiler once you are ready for production, not on day one. ReadyNative follows that: extraction is off in development, so styles stay plain runtime values, and production bundles get the compiler.

Expo Go: what runs without a build

You do not need a development build for Tamagui itself. Tamagui's docs say the core package needs no native install step. That is also why its Toast component is a separate package: the native dependency it needs would stop the core package from running in Expo Go. The ReadyNative module is marked as Expo Go compatible.

The animation driver uses react-native-reanimated. Expo's SDK 57 reference lists Reanimated as included in Expo Go, so the default animations run there as well.

Native libraries you add later, such as MMKV, still need a development build. The Expo Go vs development build post explains when that matters.

Set it up with one command

Run the setup script from the project root and pick Tamagui as the UI option. The ReadyNative docs list this flag with the other category overrides:

bun run setup --ui tamagui

Then write your colours and radius in src/theme/tokens.ts and regenerate the config. The generated tamagui.config.ts is static on purpose. The compiler loads it outside Metro, so it cannot import @/ paths.

bun run gen:theme
bun run start -- --clear

Run the start command with --clear once, so Metro and Babel pick up the compiler. Expo documents that flag as restarting the dev server and clearing the JavaScript transform caches. After the first run, a normal start is enough.

Style with styled() and tokens

A token is a name, not a number. Write $primary for a colour or $3 for a space, and Tamagui reads the value from the active theme or the scale. The Tamagui docs use the same form, for example bg="$background" and p="$4". Your own components are built with styled(), and the variants object needs as const so TypeScript can type the variant props:

import { styled, Text, YStack } from "tamagui";

export const Badge = styled(YStack, {
  alignSelf: "flex-start",
  backgroundColor: "$primary",
  borderRadius: "$full",
  paddingHorizontal: "$3",
  paddingVertical: "$1",
  variants: { tone: { danger: { backgroundColor: "$destructive" } } } as const,
});

export const BadgeText = styled(Text, { color: "$primaryForeground", fontSize: 12 });

The tone prop is typed from the variants object. Change the colours in src/theme/tokens.ts and run gen:theme, not in the Badge file, because the config registers token names from that file.

Light and dark themes

TamaguiProvider takes the config and sits at the root. Tamagui's docs say to set the starting theme with defaultTheme rather than wrapping the app in a Theme component. That keeps the fastSchemeChange setting working on native. Its Expo guide passes the system scheme in the same way:

<TamaguiProvider config={config} defaultTheme={colorScheme!}>

ReadyNative registers light and dark themes with every colour token as a key, so $card, $primaryForeground and $destructive resolve in both. Setup adds the kit's ThemeProvider to src/providers.tsx, so you do not write the provider yourself.

Animations run on Reanimated

Tamagui has several animation drivers that share one config format. Its Reanimated driver hands animatable style properties to Reanimated with worklets, so animations run on the UI thread on native. Expo's SDK 57 page gives the install command:

npx expo install react-native-reanimated react-native-worklets

Expo says babel-preset-expo adds the Reanimated Babel plugin when you install the library, so there is nothing to add to babel.config.js for Reanimated itself.

Press animations are the one thing a simulator cannot prove. ReadyNative's notes say that only a device run shows whether they behave, so test them on a real phone before you ship.

Development and production builds

The compiler works at build time, and the setup switches it per environment. Diagram two shows the split.

Where the compiler runsYour styled components and tokens feed two paths. In development, styles are runtime values. In production, the compiler resolves static styles and lowers components to native primitives.styled() and $tokensyour componentsDevelopmentruntime styles, for fast iterationdisableExtraction in developmentProduction bundlecompiler resolves static styleslowers to native primitives

The React Compiler stays on for every ReadyNative stack, Tamagui included. The template's tsc, jest and expo export checks pass with both compilers on. If press animations misbehave on a device, the FAQ explains how to switch the React Compiler off for the module.

Tamagui or another typed kit?

ReadyNative offers five UI stacks behind one component contract: NativeWind 4, NativeWind 5, Tamagui, Unistyles and plain StyleSheet. Pick Tamagui when you want a typed styling API with variants and a compiler instead of class strings. If you are also looking at Unistyles, read the Unistyles 3 guide first, then compare the two setups side by side.

Gotchas that cost an afternoon

Read next: the Tamagui module docs, or the Tamagui stack page for how it compares with the other UI options.

FAQ

What is Tamagui?

Tamagui is a UI kit, a styling engine and an optimising compiler for React Native and the web. You style components with typed props and $token values, and the compiler is optional.

Does Tamagui work in Expo Go?

Yes. The core tamagui package needs no native install step, and its Reanimated animation driver uses react-native-reanimated, which Expo includes in Expo Go for SDK 57. Native libraries you add later still need a development build.

Do I need the Tamagui compiler?

No. Tamagui recommends the compiler for production. ReadyNative turns extraction off in development and runs the compiler for production bundles, so you get fast iteration and a compiled production build.

How do I set up Tamagui in ReadyNative?

Run bun run setup --ui tamagui, then bun run gen:theme after you edit src/theme/tokens.ts. Start the app once with bun run start -- --clear so Metro and Babel pick up the compiler.

More guides