Tamagui
Sistema de design multiplataforma com compilação otimizada de estilos.
Busque em todas as páginas da documentação
Sistema de design multiplataforma com compilação otimizada de estilos.
Tamagui é um sistema de design universal para React Native (e web): tokens tipados, primitivas estilizadas (Stack, Text, Button) e um compilador que achata props de estilo em objetos otimizados. No Expo SDK 57, ele se encaixa em equipes que desejam disciplina de componentes + tokens além das classes utilitárias - com desempenho ajustado para aplicativos com muitas listas.
Cartão de receita de referência rápida - pronto para copiar e colar.
npx create-expo-app@latest MyTamaguiApp --template blank-typescript
cd MyTamaguiApp
npx expo install tamagui @tamagui/config @tamagui/core react-native-reanimated react-native-safe-area-context// tamagui.config.ts
import { config as defaultConfig } from "@tamagui/config";
import { createTamagui } from "tamagui";
export const config = createTamagui({
...defaultConfig,
tokens: {
...defaultConfig.tokens,
color: {
...defaultConfig.tokens.color,
brand: "#2563eb",
brandMuted: "#93c5fd",
},
},
themes: {
...defaultConfig.themes,
light: {
...defaultConfig.themes.light,
brand: "#2563eb",
},
dark: {
...defaultConfig.themes.dark,
brand: "#60a5fa",
},
},
});
export type AppConfig = typeof config;
declare module "tamagui" {
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
interface TamaguiCustomConfig extends AppConfig {}
}// App.tsx
import { TamaguiProvider, Theme, YStack, Text, Button } from "tamagui";
import { useColorScheme } from "react-native";
import { config } from "./tamagui.config";
export default function App() {
const scheme = useColorScheme() ?? "light";
return (
<TamaguiProvider config={config} defaultTheme={scheme}>
<Theme name={scheme}>
<YStack flex={1} padding="$4" backgroundColor="$background" gap="$3">
<Text fontSize="$6" fontWeight="700" color="$color">
Tamagui no Expo
</Text>
<Button theme="active" backgroundColor="$brand" color="white">
Continuar
</Button>
</YStack>
</Theme>
</TamaguiProvider>
);
}{
"expo": {
"plugins": ["react-native-reanimated/plugin"]
}
}Quando usar isso:
size="$4", color="$brand") com validação em tempo de compilação.Button, Card) em vez de apenas classes utilitárias.Cartão de produto com variantes, tema escuro e uma linha de lista memorizada construída com tokens Tamagui.
// components/ProductCard.tsx
import { Card, H4, Paragraph, XStack, YStack, styled } from "tamagui";
const Badge = styled(Paragraph, {
name: "Badge",
fontSize: "$1",
fontWeight: "700",
paddingHorizontal: "$2",
paddingVertical: "$1",
borderRadius: "$10",
variants: {
tone: {
sale: { backgroundColor: "$red4", color: "$red11" },
new: { backgroundColor: "$green4", color: "$green11" },
},
} as const,
defaultVariants: { tone: "new" },
});
type Props = {
title: string;
price: string;
badge?: "sale" | "new";
};
export function ProductCard({ title, price, badge = "new" }: Props) {
return (
<Card elevate bordered padding="$4" backgroundColor="$background">
<YStack gap="$2">
<XStack justifyContent="space-between" alignItems="center">
<H4 color="$color" numberOfLines={1}>
{title}
</H4>
{badge && <Badge tone={badge}>{badge === "sale" ? "SALE" : "NOVO"}</Badge>}
</XStack>
<Paragraph color="$color11" fontSize="$5" fontWeight="600">
{price}
</Paragraph>
</YStack>
</Card>
);
}// screens/CatalogScreen.tsx
import { FlatList } from "react-native";
import { YStack, Text } from "tamagui";
import { ProductCard } from "../components/ProductCard";
const PRODUCTS = [
{ id: "1", title: "Trail Runner Pro", price: "$129", badge: "new" as const },
{ id: "2", title: "Merino Base Layer", price: "$79", badge: "sale" as const },
{ id: "3", title: "Softshell Jacket", price: "$199", badge: "new" as const },
];
export function CatalogScreen() {
return (
<YStack flex={1} padding="$4" backgroundColor="$background" gap="$3">
<Text fontSize="$8" fontWeight="800" color="$color">
Catálogo
</Text>
<FlatList
data={PRODUCTS}
keyExtractor={(item) => item.id}
ItemSeparatorComponent={() => <YStack height="$3" />}
renderItem={({ item }) => (
<ProductCard title={item.title} price={item.price} badge={item.badge} />
)}
/>
</YStack>
);
}// app/_layout.tsx
import { TamaguiProvider, Theme } from "tamagui";
import { Slot } from "expo-router";
import { useColorScheme } from "react-native";
import { config } from "../tamagui.config";
export default function RootLayout() {
const scheme = useColorScheme() ?? "light";
return (
<TamaguiProvider config={config} defaultTheme={scheme}>
<Theme name={scheme}>
<Slot />
</Theme>
</TamaguiProvider>
);
}O que isso demonstra:
$ - $4 resolve para o token de espaçamento 4 da configuração.styled() com variants - tone="sale" mapeia para cores temáticas, não hexadecimais inline.Theme name={scheme} alterna objetos de tema claro/escuro de tamagui.config.ts.Card elevate bordered - Atalhos de props do Tamagui compilam para elevação apropriada para a plataforma.createTamagui mescla seus tokens, temas, fontes e mídia em um único objeto de configuração.TamaguiProvider fornece a configuração e o tema ativo para a árvore React.padding="$4" para valores numéricos na compilação/tempo de execução e achatam em objetos de estilo RN.light, dark). Componentes referenciam $color, $background, não hexadecimais codificados.@tamagui/compiler ou plugin Babel) pode otimizar ainda mais árvores estáticas - avalie quando o tamanho do pacote for importante.| Camada | Exemplo | Propósito |
|---|---|---|
tokens.color.brand | #2563eb | Paleta bruta |
themes.light.brand | #2563eb | Papel específico do tema |
| Prop do Componente | backgroundColor="$brand" | Consumo em JSX |
declare module "tamagui" {
interface TamaguiCustomConfig extends AppConfig {}
}$ e nomes de variantes.as const em objetos variants para que tone seja "sale" | "new", não string.AppConfig de tamagui.config.ts para decoradores do Storybook que precisam de temas tipados.Alguns pacotes opcionais do Tamagui precisam de resolução explícita. Se o Metro falhar em subcaminhos @tamagui/*:
// metro.config.js
const { getDefaultConfig } = require("expo/metro-config");
const config = getDefaultConfig(__dirname);
config.resolver.unstable_enablePackageExports = true;
module.exports = config;Execute npx expo start --clear após adicionar o Tamagui a um projeto existente.
TamaguiProvider ausente - tokens $ resolvem para estilos indefinidos. Correção: Envolva o layout raiz, na mesma posição de outros provedores de tema.
Nome do tema incompatível - Theme name="dark" sem uma chave dark em themes. Correção: Bifurque os temas de @tamagui/config ou defina light e dark.
Mistura de Tamagui e View bruto - Quebra o ritmo do espaçamento. Correção: Use YStack/XStack para ilhas de layout; migre incrementalmente.
Hex inline em componentes Tamagui - Anula a temática. Correção: Adicione entrada de token + tema, referencie $brand.
Ordem do plugin Reanimated - O plugin Babel do Reanimated deve ser o último em babel.config.js. Correção: Siga a documentação do Expo Reanimated ao habilitar animações junto com o Tamagui.
Props apenas para web em nativo - Algumas props de atalho visam o CSS da web. Correção: Teste em ambas as plataformas; use Platform.select em componentes estilizados personalizados quando necessário.
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
| Tamagui | Componentes com tipagem de token + compartilhamento web | Equipe quer apenas strings Tailwind |
| NativeWind | Ergonomia de classe utilitária | Você precisa de APIs de variante de primeira classe em primitivas |
| React Native Paper | Material Design pronto para uso | Linguagem de marca personalizada |
| StyleSheet + tokens | Dependências mínimas | Grande DS com muitas matrizes de variantes |
| @expo/ui | Chrome nativo SwiftUI/Compose | Linguagem de design personalizada não relacionada a widgets de plataforma |
Sim. Instale tamagui, @tamagui/config e react-native-reanimated via npx expo install. Envolva o aplicativo em TamaguiProvider e carregue tamagui.config.ts no layout raiz.
$4 referencia o token de space 4. $color referencia a função color do tema ativo. É o atalho do Tamagui para consulta de token - não uma string literal.
Espalhe defaultConfig de @tamagui/config, substitua tokens e themes, e mantenha os tipos createTamagui através da ampliação de módulo. Não copie cegamente todo o tema padrão - remova tokens não utilizados para reduzir o tamanho do pacote.
NativeWind mapeia classes Tailwind para estilos. Tamagui fornece componentes estilizados + tokens com um sistema de variantes. Equipes alérgicas a className preferem Tamagui; equipes do Tailwind web preferem NativeWind.
Defina light e dark em themes, envolva com <Theme name={scheme}> e conduza scheme de useColorScheme. Veja Modo Escuro e Esquemas de Cores.
Sim. Mantenha renderItem enxuto; extraia ProductCard como um componente separado. Evite criar novos objetos de estilo inline no callback de renderização.
Componentes Tamagui encaminham props para primitivas RN - defina accessibilityRole, accessibilityLabel e teste com VoiceOver/TalkBack. Veja Noções Básicas de Acessibilidade.
Versões da Stack: Esta página foi escrita para React 19.2.3, React Native 0.86.0 e Expo SDK 57 (
expo~57.0.4).
Revisado por Chris St. John·Última atualização: 19 de jul. de 2026