No choice here is permanent: StyleSheet objects, className and a theme library's props can live in the same app, which is how most migrations happen, one screen at a time.
| Approach | Tokens live in | Work done at | Setup | Pick it when |
|---|---|---|---|---|
| StyleSheet + constants | A theme.ts you write | Run time | None | Small apps, few screens |
| NativeWind 4 | tailwind.config.js, CSS variables | Build time | Babel 41,624 , Metro, CSS | Your team knows Tailwind 5,202 |
| Unistyles 3 2,957 | StyleSheet themes | C++ at run time | Babel plugin, native build | You like StyleSheet |
| Restyle | A typed theme object | Run time | None | Strict tokens, typed props |
| Tamagui | tamagui.config.ts | Build time (compiler) | Compiler plugin | Native and web share components |
| styled-components 247,596 | A theme context | Run time | Babel optional | Existing code only |
Ask three questions. Who writes the styles? A team fluent in Tailwind on the web is productive with NativeWind on day one. Does the web matter? Tamagui and NativeWind both render on React Native Web, but Tamagui was designed for it. How much build machinery will you own? Every Babel or Metro plugin is one more thing to update with each Expo SDK 6,418 . Whatever you pick, name colors by role (surface, ink) rather than by value (blue700), so a dark theme or a rebrand touches one file.