Start with a runnable example. Both platforms import the same components.
32 controls, icons and shared sections
Owner-approved @bubbasfw/ui@0.8.4 includes the reviewed responsive marketing sections, campaign marquee and offer badge, retaining the web Button caller-style fix. Version 0.6.0 is deprecated. Vite and Astro use the web entry; Expo and the Next.js universal example keep their NativeWind host setup.
Use Node 22.13+ and pnpm 11.15.0. The Next example runs on port 4310. Expo opens its normal development flow. The package must be rebuilt after component source changes.
Import the shared CSS once. This browser entry includes the web interop and utility styles; it needs no host NativeWind Babel or Tailwind configuration. Keep declared peers compatible and use one React/React Native Web instance. Apps provide content, cleared assets, links and actions.
Astro and Node SSR hosts render shared content before collecting StyleSheet.getSheet() from the same installed react-native-web instance. Include its returned id and textContent in the document alongside web.css so structural styles exist before hydration. Hydrate the shared header and interactive sections with the same data to enable their menus and galleries.
React, React Native, NativeWind and Tailwind remain peer dependencies. Web also needs React Native Web and React DOM. Native-only apps can omit React Native Web.
Pinned example baseline: React 19.2.3, RN 0.86.3, RNW 0.21.4, NativeWind 4.2.7, Tailwind 3.4.17. NativeWind 5 and Tailwind 4 need a separate migration.
The host app scans the package’s published source and loads both presets.
Import global CSS from the entry, with @tailwind base, @tailwind components and @tailwind utilities. Web sets important: true in its Tailwind config so utilities override RNW defaults.
Building with Xcode 27
Expo SDK 57 needs the scene-lifecycle opt-in for an iOS 27 build. Install a compatible expo-build-properties plugin and configure ios.enableSceneSupport: true before regenerating a native project. Expo 57.0.23 or newer is required; this example pins 57.0.31.
Browser and Metro checks cover their observed behavior. Device, assistive technology and release acceptance remain separate checks for each consuming app.