Sharing UI Components Across React Native and Next.js with a Monorepo
Leverage a monorepo to write a single TypeScript component that works in both React Native and Next.js, reducing duplication and keeping UI consistent.
Insight
A common misconception is that React Native and web UI must be maintained in separate codebases. By using a monorepo (Yarn Workspaces or npm workspaces) and abstracting platform‑specific primitives, you can share most of the component logic and styling. The key is to isolate the parts that differ—View vs div, StyleSheet vs CSS modules—behind a tiny platform shim.
Example
// packages/ui/Button.tsx (shared)
import { Platform } from 'react-native';
import { Pressable, Text, View } from 'react-native';
import styles from './Button.module.css'; // web CSS module
export const Button = ({ title, onPress }: { title: string; onPress: () => void }) => {
const Component = Platform.OS === 'web' ? 'button' : Pressable;
return (
<Component onPress={onPress} className={styles.btn}>
<Text>{title}</Text>
</Component>
);
};
Takeaway
Put shared UI in a workspace package, use Platform.OS or conditional imports to bridge the tiny API gaps, and you’ll ship a unified look with far less duplicated code.