Quick Start
This guide will walk you through creating a simple but functional Tamagui application from scratch. You’ll learn the core concepts and build a working example that runs on both web and native.Prerequisites
Before starting, make sure you have:- Node.js 18 or later
- A React or React Native project (or create one with
npm create tamagui@latest) - Tamagui installed (see installation guide)
Step-by-Step Guide
import { defaultConfig } from '@tamagui/config/v5'
import { createTamagui } from 'tamagui'
export const config = createTamagui(defaultConfig)
export default config
export type Conf = typeof config
declare module 'tamagui' {
interface TamaguiCustomConfig extends Conf {}
}
This configuration includes everything you need: themes, tokens, fonts, and responsive breakpoints.
import { useColorScheme } from 'react-native'
import { TamaguiProvider, type TamaguiProviderProps } from 'tamagui'
import { config } from '../tamagui.config'
export function Provider({
children,
...rest
}: Omit<TamaguiProviderProps, 'config' | 'defaultTheme'>) {
const colorScheme = useColorScheme()
return (
<TamaguiProvider
config={config}
defaultTheme={colorScheme === 'dark' ? 'dark' : 'light'}
{...rest}
>
{children}
</TamaguiProvider>
)
}
import { ExternalLink } from '@tamagui/lucide-icons'
import { Anchor, Button, H2, Paragraph, XStack, YStack } from 'tamagui'
export default function HomeScreen() {
return (
<YStack
flex={1}
alignItems="center"
justifyContent="center"
gap="$4"
padding="$4"
backgroundColor="$background"
>
<H2>Welcome to Tamagui</H2>
<Paragraph textAlign="center" color="$gray11">
Build beautiful cross-platform apps with React
</Paragraph>
<XStack gap="$3" flexWrap="wrap" justifyContent="center">
<Button theme="accent" size="$5">
Get Started
</Button>
<Button size="$5" variant="outlined">
Learn More
</Button>
</XStack>
<XStack
alignItems="center"
gap="$2"
paddingHorizontal="$3"
paddingVertical="$2"
borderRadius="$4"
backgroundColor="$blue3"
hoverStyle={{ backgroundColor: '$blue4' }}
pressStyle={{ backgroundColor: '$blue2' }}
>
<Anchor
href="https://tamagui.dev/docs"
textDecorationLine="none"
color="$blue11"
>
View Documentation
</Anchor>
<ExternalLink size="$1" color="$blue11" />
</XStack>
</YStack>
)
}
YStack (vertical), XStack (horizontal)H2, ParagraphButton, Anchor$4 for spacing, $blue3 for colorshoverStyle, pressStyle@tamagui/lucide-iconsimport { Square } from 'tamagui'
export function AnimatedCard() {
return (
<Square
size={120}
borderRadius="$6"
backgroundColor="$blue9"
borderWidth={1}
borderColor="$borderColor"
elevation="$4"
animation="bouncy"
hoverStyle={{
scale: 1.1,
backgroundColor: '$blue10',
}}
pressStyle={{
scale: 0.95,
backgroundColor: '$blue8',
}}
/>
)
}
The
animation="bouncy" prop uses Tamagui’s predefined spring animation. The component will smoothly animate when you hover or press it.import { styled, YStack } from 'tamagui'
export const Card = styled(YStack, {
padding: '$4',
borderRadius: '$4',
backgroundColor: '$background',
borderWidth: 1,
borderColor: '$borderColor',
variants: {
elevated: {
true: {
elevation: '$4',
shadowColor: '$shadowColor',
},
},
pressable: {
true: {
cursor: 'pointer',
hoverStyle: {
backgroundColor: '$backgroundHover',
borderColor: '$borderColorHover',
},
pressStyle: {
backgroundColor: '$backgroundPress',
scale: 0.98,
},
},
},
},
})
import { Card } from './components/Card'
import { H3, Paragraph } from 'tamagui'
export function Example() {
return (
<Card elevated pressable>
<H3>Card Title</H3>
<Paragraph>This is a custom styled component with variants.</Paragraph>
</Card>
)
}
import { useState } from 'react'
import { Activity, Moon, Sun } from '@tamagui/lucide-icons'
import { Button, H2, Paragraph, Separator, useTheme, XStack, YStack } from 'tamagui'
export default function DemoScreen() {
const [count, setCount] = useState(0)
const theme = useTheme()
return (
<YStack
flex={1}
alignItems="center"
justifyContent="center"
padding="$4"
gap="$4"
backgroundColor="$background"
>
<H2>Interactive Demo</H2>
<YStack
width="100%"
maxWidth={400}
padding="$5"
gap="$4"
borderRadius="$6"
backgroundColor="$gray2"
borderWidth={1}
borderColor="$borderColor"
>
<Paragraph textAlign="center" fontSize="$6" fontWeight="bold">
Count: {count}
</Paragraph>
<XStack gap="$3" justifyContent="center">
<Button
theme="accent"
icon={Activity}
onPress={() => setCount(count + 1)}
>
Increment
</Button>
<Button
variant="outlined"
onPress={() => setCount(0)}
>
Reset
</Button>
</XStack>
<Separator />
<YStack gap="$2">
<Paragraph fontSize="$3" color="$gray11">
Current theme: {theme.name}
</Paragraph>
<XStack gap="$2">
<Button size="$3" theme="light" icon={Sun}>
Light
</Button>
<Button size="$3" theme="dark" icon={Moon}>
Dark
</Button>
</XStack>
</YStack>
</YStack>
<Paragraph textAlign="center" color="$gray10" maxWidth={300}>
This example works identically on web and native with zero platform-specific code.
</Paragraph>
</YStack>
)
}
Understanding Core Concepts
Stack Components
Tamagui provides three core layout primitives:- YStack - Vertical flexbox container (
flexDirection: 'column') - XStack - Horizontal flexbox container (
flexDirection: 'row') - ZStack - Stacked positioning container (overlapping children)
Design Tokens
All values starting with$ are design tokens:
- Spacing:
$1through$20(plus$0.25,$0.5,$0.75) - Sizes:
$true,$1through$10 - Colors:
$red1through$red12,$blue1through$blue12, etc. - Radii:
$1through$12
Responsive Props
Make components responsive using media query props:Themes
Switch themes dynamically:Next Steps
Why Tamagui?
Learn about the benefits and when to use Tamagui
Styled Function
Deep dive into creating custom styled components
Components
Explore the full component library
Themes
Master the theming system