Tamagui Tailwind brings Tailwind utility classes to Tamagui’s className prop. The
compiler turns them into atomic CSS at build time, and the same string renders on web
and React Native from one source file.
Tailwind CSS is a trademark of Tailwind Labs Inc.; Tamagui is not affiliated with or endorsed by Tailwind Labs.
Choose the Tamagui Tailwind frontend by import:
Then write components with utility classes:
On web that compiles to atomic CSS. On iOS and Android the same classes resolve to React Native styles. No separate stylesheet, no Babel plugin specific to Tailwind, no second styling system to learn.
The problem
Two groups of people keep running into the same wall.
The first is teams who built a web app in Tailwind and now want to ship a React Native app that shares components. Tailwind is web-first. Moving a component to native means rewriting its styles in whatever the native styling layer expects, then keeping two copies in sync as the design changes.
The second is developers who already know Tailwind and would rather not learn a new prop API to get cross-platform output. Muscle memory for flex-row items-center gap-3 is real. Asking someone to relearn it as a different set of props is friction with no payoff for them.
Tamagui already solves the cross-platform styling problem. What it did not have
was the Tailwind syntax on the front of it. @tamagui/tailwind adds that syntax
without giving up the compiler, the theme system, or the component library
underneath.
How the compiler works
When the compiler sees a className, it splits the string and maps each utility to a style. bg-blue-500 becomes a backgroundColor, p-4 becomes padding of 16px, rounded-lg becomes a border radius. Each resolved style is written as one atomic CSS rule and deduplicated across your whole app, so p-4 exists exactly once in the output no matter how many components use it.
Color and radius utilities resolve through your token system. bg-blue-500 looks up the Tailwind palette entry and emits a CSS variable reference, which means it participates in theming rather than hard-coding a hex value. Numeric spacing and sizing follow Tailwind’s scale, so p-4 is 16px and gap-2 is 8px. A color name that is not a palette token passes straight through as a literal CSS value, so bg-red resolves to backgroundColor: red.
Modifiers compile too. hover:bg-blue-600 extracts a hover rule into its own atomic class. sm:p-6 becomes a media-query rule. Combined modifiers like sm:hover:bg-purple-500 produce a single rule scoped to both the breakpoint and the pseudo-state. These are static, so they go in the stylesheet and cost nothing at runtime.
Classes the compiler does not recognize are left alone. If you write my-custom-class, it passes through to the rendered element’s className untouched, so your own CSS keeps working alongside the utilities.
Some values cannot become static rules, and the compiler is explicit about them. Physics springs, gesture-linked motion, and parent-driven native states need runtime state to resolve. CSS transitions with conditional opacity and transform values can compile on web, while truly dynamic values remain inline or use Tamagui’s runtime style path.
What compiles today
The utilities that resolve cross-platform cover the layout surface you reach for most: sizing (w-24, h-8, size-10, w-1/2, min-w-24, max-h-20), spacing (p-4, px-6, pt-8, m-4), flexbox and alignment (flex, flex-row, flex-1, items-center, justify-between, self-end, gap-2), typography (text-sm, text-white, text-center, text-[14px], font-bold, font-sans, leading-8, tracking-1), the full color palette for backgrounds and borders (bg-indigo-500, border-red-500), border radius including corners (rounded-md, rounded-t-xl, rounded-tl-lg, rounded-full), border width including sides (border, border-4, border-t-4, border-x), position (relative, absolute, inset-0, inset-x-0, inset-y-4, top-2, z-10), opacity (opacity-50), and overflow.
text-* follows Tailwind’s split: alignment keywords (text-center), the type scale (text-sm), palette and theme colors (text-white), and arbitrary lengths or colors (text-[14px], text-[#fff]). Unrecognized classes pass through on web and drop on native rather than throwing. Web-only leftovers (grid, float, backdrop filters, sibling space-x / divide-x) stay with the official Tailwind engine. The full remainder is in plans/v3-beta/tailwind-coverage.md.
Performance
The web benchmark renders 200 items, or 60 in the heavy case, in production
Chromium on an Apple M5 Pro. Each arm gets two warmup rounds and 10 retained
rounds. Seed 73129 reshuffles framework and scenario order each round, and a
rendered-behavior gate runs before timing. The table reports mean milliseconds.
Simple, rich, group, and heavy use Tamagui beta 901. Animated uses beta 917.
| Scenario | Operation | Tamagui Tailwind compiled | Tailwind CSS | Inline React | NativeWind v5 | Uniwind |
|---|---|---|---|---|---|---|
| Simple | Mount | 0.45 | 0.35 | 0.53 | 1.60 | 1.71 |
| Simple | Update | 0.96 | 0.98 | 0.90 | 2.43 | 2.35 |
| Simple | Remount | 0.55 | 0.44 | 0.63 | 1.72 | 1.80 |
| Rich | Mount | 0.57 | 0.33 | 0.90 | 1.73 | 1.64 |
| Rich | Update | 1.14 | 1.06 | 1.07 | 2.39 | 2.59 |
| Rich | Remount | 0.67 | 0.43 | 0.98 | 1.82 | 2.11 |
| Group | Mount | 0.71 | 0.80 | 1.38 | 4.21 | 5.24 |
| Group | Update | 2.23 | 2.53 | 2.18 | 6.00 | 6.92 |
| Group | Remount | 0.92 | 1.10 | 1.83 | 5.75 | 6.10 |
| Heavy | Mount | 0.72 | 0.63 | 1.01 | 2.95 | 3.11 |
| Heavy | Update | 1.67 | 1.80 | 1.70 | 4.52 | 4.42 |
| Heavy | Remount | 1.06 | 0.93 | 1.34 | 3.59 | 4.00 |
| Animated | Mount | 0.42 | 0.31 | 0.57 | 1.21 | 1.07 |
| Animated | Update | 1.91 | 1.14 | 1.25 | 1.96 | 1.81 |
| Animated | Remount | 2.01 | 1.98 | 2.35 | 2.81 | 2.95 |
- Scenario
- Simple
- Operation
- Mount
- Tamagui Tailwind compiled
- 0.45
- Tailwind CSS
- 0.35
- Inline React
- 0.53
- NativeWind v5
- 1.60
- Uniwind
- 1.71
- Scenario
- Simple
- Operation
- Update
- Tamagui Tailwind compiled
- 0.96
- Tailwind CSS
- 0.98
- Inline React
- 0.90
- NativeWind v5
- 2.43
- Uniwind
- 2.35
- Scenario
- Simple
- Operation
- Remount
- Tamagui Tailwind compiled
- 0.55
- Tailwind CSS
- 0.44
- Inline React
- 0.63
- NativeWind v5
- 1.72
- Uniwind
- 1.80
- Scenario
- Rich
- Operation
- Mount
- Tamagui Tailwind compiled
- 0.57
- Tailwind CSS
- 0.33
- Inline React
- 0.90
- NativeWind v5
- 1.73
- Uniwind
- 1.64
- Scenario
- Rich
- Operation
- Update
- Tamagui Tailwind compiled
- 1.14
- Tailwind CSS
- 1.06
- Inline React
- 1.07
- NativeWind v5
- 2.39
- Uniwind
- 2.59
- Scenario
- Rich
- Operation
- Remount
- Tamagui Tailwind compiled
- 0.67
- Tailwind CSS
- 0.43
- Inline React
- 0.98
- NativeWind v5
- 1.82
- Uniwind
- 2.11
- Scenario
- Group
- Operation
- Mount
- Tamagui Tailwind compiled
- 0.71
- Tailwind CSS
- 0.80
- Inline React
- 1.38
- NativeWind v5
- 4.21
- Uniwind
- 5.24
- Scenario
- Group
- Operation
- Update
- Tamagui Tailwind compiled
- 2.23
- Tailwind CSS
- 2.53
- Inline React
- 2.18
- NativeWind v5
- 6.00
- Uniwind
- 6.92
- Scenario
- Group
- Operation
- Remount
- Tamagui Tailwind compiled
- 0.92
- Tailwind CSS
- 1.10
- Inline React
- 1.83
- NativeWind v5
- 5.75
- Uniwind
- 6.10
- Scenario
- Heavy
- Operation
- Mount
- Tamagui Tailwind compiled
- 0.72
- Tailwind CSS
- 0.63
- Inline React
- 1.01
- NativeWind v5
- 2.95
- Uniwind
- 3.11
- Scenario
- Heavy
- Operation
- Update
- Tamagui Tailwind compiled
- 1.67
- Tailwind CSS
- 1.80
- Inline React
- 1.70
- NativeWind v5
- 4.52
- Uniwind
- 4.42
- Scenario
- Heavy
- Operation
- Remount
- Tamagui Tailwind compiled
- 1.06
- Tailwind CSS
- 0.93
- Inline React
- 1.34
- NativeWind v5
- 3.59
- Uniwind
- 4.00
- Scenario
- Animated
- Operation
- Mount
- Tamagui Tailwind compiled
- 0.42
- Tailwind CSS
- 0.31
- Inline React
- 0.57
- NativeWind v5
- 1.21
- Uniwind
- 1.07
- Scenario
- Animated
- Operation
- Update
- Tamagui Tailwind compiled
- 1.91
- Tailwind CSS
- 1.14
- Inline React
- 1.25
- NativeWind v5
- 1.96
- Uniwind
- 1.81
- Scenario
- Animated
- Operation
- Remount
- Tamagui Tailwind compiled
- 2.01
- Tailwind CSS
- 1.98
- Inline React
- 2.35
- NativeWind v5
- 2.81
- Uniwind
- 2.95
On beta 901, compiled Tamagui Tailwind had lower mount means than NativeWind and Uniwind in simple, rich, group, and heavy. The paired 95% confidence intervals for all eight comparisons were below zero. Its whole-app JavaScript was 111,808 bytes gzipped, with 47,925 bytes attributed to the framework and 1,093 bytes of CSS gzip. Those bundle figures also use beta 901.
The animated fixture uses a CSS transition with conditional opacity and
transform values. On beta 917 the compiler found, lowered, and flattened all 14
View candidates in the fixture source with zero bailouts. Tamagui Tailwind
compiled measured 0.42ms mount, 1.91ms update, and 2.01ms remount.
Direct paired effects report Tamagui Tailwind minus each rival. Against NativeWind, the differences were -0.79ms for mount (95% CI -0.988 to -0.592), -0.05ms for update (-0.376 to 0.276), and -0.80ms for remount (-1.066 to -0.534). Against Uniwind, they were -0.65ms (-0.741 to -0.559), 0.10ms (-0.176 to 0.376), and -0.94ms (-1.445 to -0.435). Tamagui Tailwind was lower for mount and remount against both native utility libraries, while neither update interval resolved a difference.
Against Tailwind CSS, the paired differences were 0.11ms for mount (0.001 to 0.219), 0.77ms for update (0.529 to 1.011), and 0.03ms for remount (-0.256 to 0.316). Tailwind CSS was lower for mount and update; the remount interval did not resolve a difference. These are results for this fixture on this machine, not a universal framework ranking.
The beta 901 compiler build flattened the group and heavy fixture elements. It left the heavy fixture’s computed widths as dynamic values while extracting the static utility work. Its one source-wide bailout was the older animated conditional. Beta 917 closed that animated bailout without changing the fixture. The benchmark covers a CSS transition, not a physics spring or gesture-linked animation.
Cross-platform coverage
The beta 891 coverage harness derives all 23,286 candidates from Tailwind CSS 4.3.0’s installed utility registry instead of a hand-maintained list. It runs each library’s parser or compiler on both targets.
| Framework | Web resolved | Native styles | Native share of registry |
|---|---|---|---|
| Tamagui Tailwind | 23,286 | 4,522 | 19.42% |
| NativeWind v5 | 23,286 | 20,500 | 88.04% |
| Uniwind | 23,286 | 22,352 | 95.99% |
- Framework
- Tamagui Tailwind
- Web resolved
- 23,286
- Native styles
- 4,522
- Native share of registry
- 19.42%
- Framework
- NativeWind v5
- Web resolved
- 23,286
- Native styles
- 20,500
- Native share of registry
- 88.04%
- Framework
- Uniwind
- Web resolved
- 23,286
- Native styles
- 22,352
- Native share of registry
- 95.99%
Tamagui Tailwind resolves all 23,286 classes on web. Of those, 4,522 become Tamagui styles and 18,764 pass through to CSS. The same 4,522 return React Native styles on native. Beta 891 closed the named text color and size, font, size, corner radius, single-side border, and axis inset gaps. Its largest remaining native gaps are masks, gradients, shadows, rings, outlines, and logical-direction borders.
The registry contains web-only CSS, so these percentages describe each compiler’s accepted native surface. They do not claim that React Native can visually reproduce every CSS utility.
One component, both platforms
This renders on web and native from the same file. No platform branches, no second stylesheet.
On web that compiles to atomic CSS classes in the bundle. On iOS and Android the same string resolves to React Native styles. The visual output matches pixel for pixel against real Tailwind for the utilities in our conformance suite, which is how we verify the native mapping rather than trusting a screenshot.
Regular Tamagui and Tailwind components can share the same tree. Each component keeps one styling language, selected by its import:
Theme tokens like blue-5 respond to light and dark mode the way they always
have. Both components still use the shared renderer, themes, and platform
behavior.
Getting started
Install the latest Tamagui and the v6 config, which ships the Tailwind palette, the named radii, and the w/h shorthands the utility parser needs:
yarn
npm
bun
pnpm
Keep your ordinary Tamagui config and import the Tailwind components where you want utility authoring:
Write a component:
Build it. The compiler extracts the CSS, and the component renders on web and native with the static styles already resolved.
If you are on Tailwind today and want native output without rewriting your styles, this is the path. The compiler, the themes, the animation drivers, and the component library are all still there when you reach for them.