Summary
I've been working on create-rnstack, a production-ready React Native starter built on top of React Native Reusables.
As part of that work, I migrated the entire component library to:
- NativeWind v5 Preview
- Tailwind CSS v4
- Expo SDK 56
- React Native 0.85
- New Architecture
While doing this, I found a few native-only issues that required component changes before everything rendered correctly.
I'm sharing the findings here so:
- future NativeWind v5 users don't have to rediscover the same fixes,
- maintainers have a consolidated migration reference,
- these improvements can be incorporated once v5 becomes stable.
Repository used for validation:
Environment
nativewind@5.0.0-preview.4
react-native-css@3.x
tailwindcss@4
Expo SDK 56
React Native 0.85
New Architecture
Reanimated 4
Components requiring changes
1. icon.tsx
Problem
The current implementation still relies on cssInterop.
Under NativeWind v5 the styling runtime has moved to react-native-css, so className is no longer correctly forwarded to the icon on native.
Expected
className should continue controlling:
Switching to styled() fixes the issue.
import { styled } from "react-native-css";
const IconImpl = styled(IconBase, {
className: {
target: "style",
nativeStyleToProp: {
height: "size",
width: "size",
},
},
});
2. input.tsx
Problem
Android TextInput has two issues:
- descenders (g, j, p, y) get clipped
- empty inputs collapse vertically
Expected
Wrapping the input inside a fixed-height container while disabling Android font padding fixes both.
<View className="h-10 flex-row items-center">
<TextInput
className="flex-1 p-0"
style={{
includeFontPadding: false,
textAlignVertical: "center",
}}
/>
</View>
3. textarea.tsx
Problem
placeholderClassName no longer reliably themes placeholder colors on native.
Dark mode placeholders become invisible.
Expected
Use Tailwind's placeholder: utilities directly inside className.
className="... placeholder:text-muted-foreground"
4. select.tsx
(Related: #534)
Problem
w-[--radix-select-trigger-width]
is web-only.
On native the dropdown width becomes incorrect.
Expected
The trigger width is already measured internally.
Using
useRootContext().triggerPosition.width
to size SelectContent makes the native implementation match the trigger width.
Additional NativeWind v5 migration notes
These are not React Native Reusables issues, but every NativeWind v5 migration will likely encounter them.
Color tokens
Avoid storing HSL channels like:
Instead store complete colors:
This prevents opacity-related flickering during theme changes on native.
Radius tokens
Avoid
calc(var(--radius) - 2px)
Native currently resolves these inconsistently.
Using explicit values is more reliable.
Metro
inlineRem: 16 is required in metro.config.js.
global.css
Use the new NativeWind v5 @import syntax instead of the old @tailwind directives.
Notes
I realize React Native Reusables has continued evolving since I originally copied these components (for example, newer overlay and animation improvements).
This issue isn't intended to compare implementations.
It's simply documenting the remaining NativeWind v5 compatibility changes that were still necessary during migration.
Happy to contribute
I'd be happy to open focused PRs for any of these components if that's useful.
If NativeWind v5 support is already planned, hopefully this validation saves some migration effort for both maintainers and users.
Further reading
I also documented the overall migration experience in a blog post for anyone interested in migrating an existing project:
https://dev.to/sanjaysah/building-react-native-shouldnt-feel-like-assembling-ikea-furniture-a-modern-monorepo-starter-kit-pef
Summary
I've been working on create-rnstack, a production-ready React Native starter built on top of React Native Reusables.
As part of that work, I migrated the entire component library to:
While doing this, I found a few native-only issues that required component changes before everything rendered correctly.
I'm sharing the findings here so:
Repository used for validation:
Environment
Components requiring changes
1. icon.tsx
Problem
The current implementation still relies on
cssInterop.Under NativeWind v5 the styling runtime has moved to
react-native-css, soclassNameis no longer correctly forwarded to the icon on native.Expected
classNameshould continue controlling:Switching to
styled()fixes the issue.2. input.tsx
Problem
Android
TextInputhas two issues:Expected
Wrapping the input inside a fixed-height container while disabling Android font padding fixes both.
3. textarea.tsx
Problem
placeholderClassNameno longer reliably themes placeholder colors on native.Dark mode placeholders become invisible.
Expected
Use Tailwind's
placeholder:utilities directly insideclassName.4. select.tsx
(Related: #534)
Problem
is web-only.
On native the dropdown width becomes incorrect.
Expected
The trigger width is already measured internally.
Using
to size
SelectContentmakes the native implementation match the trigger width.Additional NativeWind v5 migration notes
These are not React Native Reusables issues, but every NativeWind v5 migration will likely encounter them.
Color tokens
Avoid storing HSL channels like:
Instead store complete colors:
This prevents opacity-related flickering during theme changes on native.
Radius tokens
Avoid
Native currently resolves these inconsistently.
Using explicit values is more reliable.
Metro
inlineRem: 16is required inmetro.config.js.global.css
Use the new NativeWind v5
@importsyntax instead of the old@tailwinddirectives.Notes
I realize React Native Reusables has continued evolving since I originally copied these components (for example, newer overlay and animation improvements).
This issue isn't intended to compare implementations.
It's simply documenting the remaining NativeWind v5 compatibility changes that were still necessary during migration.
Happy to contribute
I'd be happy to open focused PRs for any of these components if that's useful.
If NativeWind v5 support is already planned, hopefully this validation saves some migration effort for both maintainers and users.