The how and why of Tamagui
Tamagui lets you share more code between web and native apps while improving, rather than sacrificing, DX, performance, and code maintainability.
It does this by compiling typed inline styles - even ones containing conditional logic, themes, or responsivity - into efficient atomic CSS (or a hoisted StyleSheet on native).
This is a win-win-win: more performant, easier to write/maintain, and works on every platform. Typically you'd have to trade performance for DX, or both for cross-platform compatibility. With Tamagui, you don't!
In exchange you add some complexity with the compiler - but - it's both optional and very easy to granularly introspect or turn off.
The compiler does a lot, too - it analyzes logic, spreads, and nested ternaries, even flattening fully analyzable components to reduce tree depth signficantly.
Work with your favorite libraries:
react-native-web augmenting them with features and performance.
Inline typed theme and media props, and accompanying
useMedia hooks work how you'd expect them to, but also compile away.
Almost no prop interpolation on inline styles and dynamic styles. Even with complex logical styling you get less runtime, light CSS output, and flatter component trees. CSS media queries and CSS variables run much faster than JS.
Tamagui adds some to bundle size, but dramatically reduces render performance and extract what would be many style objects out at build time. Strictly style components (with no un-parseable props) are flattened to
span, saving tree depth and hook calls.
Tamagui supports cross-browser server-side rendering (see how we do it with Next.js ), even for responsive styles and variants.
Variants as a first-class citizen, so you can design composable component APIs. Define a single variant, multiple variants, and even Spread Variants which allow you to return dynamic styles, even at compile-time.
Define your own tokens and seamlessly apply them as CSS values. CSS Properties are automatically mapped to token scales. Tokens can even be used in shorthand CSS properties.
Tamagui provides a simple theming experience out of the box. Create as many themes as you need, and apply them wherever you want. Each theme generates a CSS class name which overrides the default tokens.
Shorthands allow you to map shorthand properties to their longer cousins. This lets you create Tailwinds-like quick properties to style. These work with TypeScript as well, and are designed so you can bring them with you across different tamagui component kits.
Tamagui lets you configure media queries and apply variants responsively using
Plug-in animations with incredibly simple syntax.
A unique font system means you can publish and share font bundles including all their styles - vertical rythyms and all, and still get all the benefits of compilation speed.
useTheme hooks work reactively, avoiding re-renders, while giving you the same typed access as your normally have to your design system values. They work with the compiler as well when possible.
Tamagui provides a fully-typed API so all your TypeScript style properties, values, media queries and shorthands will be auto-completed for you. It provides a
// debug pragma and
debug prop that both allow easy introspection into whats happening at compile and runtime. In dev mode it puts a
data- attribute that links every DOM node back to your original source.
Inline styles have a few developer-speed benefits over
StyleSheet.create: they require fewer imports and fewer lines of code, and they save you from jumping between the top and bottom of your file whenever you want to change a style so you can see exactly whats happening where it's happening.
StyleSheet.create forces you to manually link together the style with the node that's using the style. When you delete the style, you must delete the node, and when you delete a node, you have to manually check to be see if any other node is using that style before removing it.
Fast inline styles and common tokens mean less having to name things. Shorthand style props that are flat often make the difference between one line and multiple.
Changing between a style that's determined by a ternary or conditional and one that's static shouldn't be a hard choice. With StyleSheet there's some friction as you have to either inline it and save time and readability or extract it to the bottom and gain performance. With inline styles (and the compiler) you no longer have that friction: convert any prop to have a ternary and it works the same, and runs fast.
We're excited to see the community adopt Tamagui, raise issues, and provide feedback. Whether it's a feature request, bug report, or a project to showcase, please get involved!
A big thanks to: