---
name: tamagui-best-practices
description: Use when working with Tamagui projects (tamagui.config.ts, @tamagui imports).
---
# Tamagui Best Practices
Tamagui v1.x patterns beyond fundamentals: Config v4, compiler optimization, compound components, and gotchas.
## Reference Files — Read Before Writing Code
| Context | File | What it covers |
|---------|------|----------------|
| Dialog, Sheet, modal overlays | @DIALOG_PATTERNS.md | Adapt component, accessibility |
| Form, Input, Label, validation | @FORM_PATTERNS.md | zod integration |
| Animations, transitions | @ANIMATION_PATTERNS.md | drivers, enterStyle/exitStyle |
| Popover, Tooltip, Select | @OVERLAY_PATTERNS.md | overlay primitives |
| Compiler optimization | @COMPILER_PATTERNS.md | what the compiler can/cannot flatten |
| Design tokens, theming | @DESIGN_SYSTEM.md | palette, token structure |
## Config v4
Minimal setup with `@tamagui/config/v4`. Add `styleCompat: 'react-native'` for new projects to align `flexBasis` with React Native behavior:
```tsx
import { defaultConfig } from '@tamagui/config/v4'
import { createTamagui } from 'tamagui'
export const config = createTamagui({
...defaultConfig,
settings: { ...defaultConfig.settings, styleCompat: 'react-native' },
})
declare module 'tamagui' {
interface TamaguiCustomConfig extends typeof config {}
}
```
For custom themes use `createThemes` with `palette`/`accent`/`childrenThemes` — see @DESIGN_SYSTEM.md.
## Compiler Optimization Rules
- Use `styled()` variants instead of inline conditionals — dynamic values break flattening.
- Avoid `style={{ ... }}` with variables; use variant props instead.
- The `context` pattern (createStyledContext) disables compiler flattening — use for higher-level components (Button, Card), not primitives.
```tsx
// BAD — breaks compiler
// GOOD — use variants
const Box = styled(View, {
variants: {
dark: { true: { backgroundColor: '$gray1' }, false: { backgroundColor: '$gray12' } },
},
})
```
## styled() vs Inline
- `styled()`: reusable components, variant-driven behavior, compiler-optimizable primitives.
- Inline props: one-off layout adjustments on already-styled components.
- Always use `as const` on `variants` objects (TypeScript limitation until inferred const generics).
## Key Gotchas
**Prop order determines override priority** — props after a spread cannot be overridden by callers:
```tsx
// width is locked; backgroundColor can be overridden
```
**Variant order matters** — later props win:
```tsx
// scale = 3 (scale listed first)
// scale = 2 (huge overrides, comes first in variants)
```
**Use `.styleable()` when wrapping styled components** — preserves variant inheritance:
```tsx
const CorrectWrapper = StyledText.styleable((props, ref) => (
))
```
**`accept` prop for non-standard token resolution** (SVG fill/stroke, contentContainerStyle):
```tsx
const StyledSVG = styled(SVG, {}, { accept: { fill: 'color', stroke: 'color' } as const })
```
**Import consistency** — `tamagui`, `@tamagui/core`, and `@tamagui/button` are different packages; pick one approach per project.
**Never mix RN StyleSheet with Tamagui** — StyleSheet values don't resolve tokens.
**Platform branching for Dialog/Sheet** — use `Adapt` instead of `Platform.OS` checks (see @DIALOG_PATTERNS.md).
## Quick Reference
**Config v4 shorthands**: `bg` backgroundColor, `p` padding, `m` margin, `w` width, `h` height, `br` borderRadius
**Media breakpoints**: `$xs` 660px, `$sm` 800px, `$md` 1020px, `$lg` 1280px, `$xl` 1420px
**Animation drivers**: `css` (web, default), `react-native-reanimated` (native, required)
**Token `$` prefix**: use in props (`color="$color"`), omit in theme definitions (`{ color: palette[11] }`)
## Fetching Current Docs
```bash
curl -sL "https://tamagui.dev/docs/core/configuration.md"
curl -sL "https://tamagui.dev/llms.txt" # full index
```