Monorepo Strategy: Sharing UI Components Across React Native and Web
Learn how to structure a monorepo so React Native and web projects can import the same TypeScript UI components, reducing duplication and keeping styles in sync.
Insight
A monorepo with a shared ui package lets you write a component once and reuse it in both React Native and web (e.g., Next.js). By using TypeScript path aliases and conditional imports, you can keep platform‑specific implementations isolated while exposing a common API. This reduces maintenance overhead and guarantees visual consistency across platforms.
Example
// tsconfig.json (root)
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@myapp/ui": ["packages/ui/src/index.ts"]
}
}
}
// 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: Platform.OS === 'web' ? '#007aff' : '#2196f3' }}>
<Text style={{ color: '#fff' }}>{title}</Text>
</TouchableOpacity>
);
// apps/mobile/App.tsx
import { Button } from '@myapp/ui';
// apps/web/pages/index.tsx
import { Button } from '@myapp/ui';
Takeaway
Set up a root tsconfig with path aliases and place UI primitives in a dedicated package. Then import them from any app in the monorepo. This pattern gives you a single source of truth for components, speeds up iteration, and keeps your bundle sizes lean.