~/swaraj.dev
Back to all posts
June 3, 20261 min read

Sharing UI Components Across React Native and Next.js with a Monorepo

Learn how a Yarn workspace monorepo lets you write a single UI component library that works in both React Native and Next.js, cutting duplication and keeping styles in sync.

monoreporeact nativenext.jstypescriptshared code

Insight

A single source of truth for UI components dramatically reduces maintenance overhead when you ship both a mobile app (React Native) and a web companion (Next.js). By placing shared components in a packages/ui folder and using Yarn workspaces, you can resolve the same TypeScript paths in both environments. The key is to keep platform‑specific imports (react-native vs react-dom) abstracted behind a thin shim that re‑exports the appropriate primitives.

Example

// packages/ui/src/Button.tsx
import { Platform, TouchableOpacity, Text } from 'react-native';

export const Button = ({ title, onPress }: { title: string; onPress: () => void }) => (
  <TouchableOpacity onPress={onPress} style={{ padding: 12, backgroundColor: '#0066ff' }}>
    <Text style={{ color: '#fff' }}>{title}</Text>
  </TouchableOpacity>
);

// packages/web-shim/src/react-native.ts
export * from 'react-native-web'; // maps RN components to web equivalents

In next.config.js add an alias: { alias: { 'react-native': 'react-native-web' } }.

Takeaway

Set up a Yarn workspace monorepo, place UI code in a shared package, and use platform shims (e.g., react-native-web) to let the same component render on both mobile and web without duplication. This pattern scales nicely as your app grows.