What happened?
On native platforms, Uniwind stops applying className styles to every component that comes from node_modules (e.g. all of HeroUI Native's Card, Surface, Button, etc. render with no background, padding, radius or fill) whenever the app's absolute path contains a directory named react-native, e.g. ~/Developer/react-native/my-app. The same class strings work on Views in the app's own source.
Root cause: nativeResolver in packages/uniwind/src/bundler/adapters/metro/resolvers.ts decides whether a module is React Native internals with a substring match on the whole absolute path:
const isFromNodeModules = context.originModulePath.includes(`${sep}node_modules${sep}`)
const isFromReactNative = context.originModulePath.includes(`${sep}react-native${sep}`)
|| context.originModulePath.includes(`${sep}@react-native${sep}`)
// ...
|| (isFromReactNative && isFromNodeModules && !isReactNativeAnimated) // Is from react-native but not Animated
For /Users/me/Developer/react-native/my-app/node_modules/heroui-native/lib/module/components/surface/surface.js, both flags are true (because of the parent react-native/ folder), so the react-native → uniwind/components rewrite is skipped for every dependency. App files don't contain /node_modules/, so they keep working, which makes this look like a component-library bug.
Quick check:
const p = '/Users/me/Developer/react-native/my-app/node_modules/heroui-native/lib/module/components/surface/surface.js'
p.includes('/node_modules/') && p.includes('/react-native/') // true → resolver skips the swap
Suggested fix (only look at the path after the last node_modules segment). We're running this as a local pnpm patch, and it fixes the problem while keeping the React Native internals and the Animated exception behaving as before:
const afterNodeModules = context.originModulePath.split(`${sep}node_modules${sep}`).at(-1) ?? ''
const isFromReactNative = afterNodeModules.startsWith(`react-native${sep}`)
|| afterNodeModules.startsWith(`@react-native${sep}`)
(startsWith('react-native' + sep) also avoids matching sibling packages like react-native-svg.)
Steps to Reproduce
mkdir -p /tmp/react-native && cd /tmp/react-native. The parent folder name is what matters.
- Create an Expo app there and set up Uniwind + HeroUI Native per their quick-starts (
withUniwindConfig in metro.config.js, global.css importing tailwindcss, uniwind, heroui-native/styles, app wrapped in GestureHandlerRootView + HeroUINativeProvider).
- Render
<Card><Card.Body><Card.Title>Hi</Card.Title></Card.Body></Card> and <Button>Press</Button>.
- Run on Android. The Card and Button have no background, radius, padding or fill.
- Move the same project to a path without a
react-native segment (e.g. /tmp/rn/…), clear the Metro cache, and run again. The components are styled correctly.
Snack or Repository Link
No repository link: the bug depends only on the directory the project is cloned into, not on its contents, so any repo reproduces it once it's placed under a react-native/ folder (steps above). Happy to put one up if you'd still like it.
Uniwind version
1.12.0 (the same code is on main)
React Native Version
0.86.3 (Expo SDK 57; heroui-native 1.0.9 and 1.0.10)
Platforms
Android (the code path is the native resolver, so iOS should be affected the same way)
Expo
Yes
Additional information
What happened?
On native platforms, Uniwind stops applying
classNamestyles to every component that comes fromnode_modules(e.g. all of HeroUI Native'sCard,Surface,Button, etc. render with no background, padding, radius or fill) whenever the app's absolute path contains a directory namedreact-native, e.g.~/Developer/react-native/my-app. The same class strings work onViews in the app's own source.Root cause:
nativeResolverinpackages/uniwind/src/bundler/adapters/metro/resolvers.tsdecides whether a module is React Native internals with a substring match on the whole absolute path:For
/Users/me/Developer/react-native/my-app/node_modules/heroui-native/lib/module/components/surface/surface.js, both flags aretrue(because of the parentreact-native/folder), so thereact-native→uniwind/componentsrewrite is skipped for every dependency. App files don't contain/node_modules/, so they keep working, which makes this look like a component-library bug.Quick check:
Suggested fix (only look at the path after the last
node_modulessegment). We're running this as a localpnpm patch, and it fixes the problem while keeping the React Native internals and the Animated exception behaving as before:(
startsWith('react-native' + sep)also avoids matching sibling packages likereact-native-svg.)Steps to Reproduce
mkdir -p /tmp/react-native && cd /tmp/react-native. The parent folder name is what matters.withUniwindConfiginmetro.config.js,global.cssimportingtailwindcss,uniwind,heroui-native/styles, app wrapped inGestureHandlerRootView+HeroUINativeProvider).<Card><Card.Body><Card.Title>Hi</Card.Title></Card.Body></Card>and<Button>Press</Button>.react-nativesegment (e.g./tmp/rn/…), clear the Metro cache, and run again. The components are styled correctly.Snack or Repository Link
No repository link: the bug depends only on the directory the project is cloned into, not on its contents, so any repo reproduces it once it's placed under a
react-native/folder (steps above). Happy to put one up if you'd still like it.Uniwind version
1.12.0 (the same code is on
main)React Native Version
0.86.3 (Expo SDK 57; heroui-native 1.0.9 and 1.0.10)
Platforms
Android (the code path is the native resolver, so iOS should be affected the same way)
Expo
Yes
Additional information
isInternalpath-classification bug in the same resolver)