A production-ready microapps architecture using Expo Router and Yarn workspaces for scalable React Native development.
A comprehensive monorepo solution that demonstrates how to build scalable mobile applications using a microapps architecture. Each microapp can function both as a standalone application and as an embedded component within a main super-app.
- π― Dual-Purpose Architecture: Each microapp works standalone AND embedded
- π± Expo Router Integration: File-based routing with universal deep linking
- π οΈ CLI-Driven Development: Generate new microapps with a single command
- π Zero Dependency Duplication: Shared workspace dependencies
- π¨ Type-Safe Development: Full TypeScript support with path mapping
- π Hot Reload Everywhere: Development experience across all apps
- π¦ Modular Package System: Reusable components and shared state
expo-modular-apps/
βββ apps/
β βββ main-app/ # Super app (tab-based)
β βββ ecommerce-app/ # Standalone e-commerce app (CLI-generated)
β βββ banking-app/ # Standalone banking app (CLI-generated)
β βββ social-app/ # Standalone social app (CLI-generated)
βββ packages/
β βββ shared-types/ # Common TypeScript definitions
β βββ ecommerce-microapp/ # Embeddable e-commerce component (CLI-generated)
β βββ banking-microapp/ # Embeddable banking component (CLI-generated)
β βββ social-microapp/ # Embeddable social component (CLI-generated)
βββ tools/
β βββ microapp-cli/ # CLI for generating microapps
βββ package.json # Yarn workspace configuration
- Main App: A super-app with tab navigation where each tab hosts a microapp
- Standalone Apps: Independent Expo Router apps for each microapp
- Microapp Packages: Embeddable React components that power both modes
- Shared Dependencies: All apps share the same React Native/Expo dependencies
- Type Safety: Shared TypeScript definitions across the entire monorepo
- Node.js 18+ and Yarn 1.x
- Expo CLI (
npm install -g @expo/cli
) - iOS Simulator or Android Emulator (for testing)
# Clone the repository
git clone https://github.com/Alvinotuya84/expo-modular-apps.git
cd expo-modular-apps
# Install dependencies
yarn install
# Start the main super-app
yarn dev
# Generate a new microapp
yarn microapp create loyalty
# This creates:
# - apps/loyalty-app (standalone app)
# - packages/loyalty-microapp (embeddable component)
# - Tab integration in main app
This repository includes three working examples generated using the CLI:
# Examples were created using these commands:
yarn microapp create ecommerce # E-commerce functionality
yarn microapp create banking # Financial services
yarn microapp create social # Social networking features
# Main super-app
yarn dev # Start main app
yarn dev:main # Alternative main app command
# Standalone microapps
yarn workspace ecommerce-app start # Start e-commerce app
yarn workspace banking-app start # Start banking app
yarn workspace social-app start # Start social app
# Create a new microapp
yarn microapp create <name> # Interactive creation
yarn microapp create <name> --type standalone # Standalone only
yarn microapp create <name> --type package # Package only
yarn microapp create <name> --skip-install # Skip dependency install
# List all microapps
yarn microapp list # Show all apps and packages
# Add tab to main app
yarn microapp add-tab <name> # Add existing microapp as tab
# Build all workspaces
yarn build
# Lint all code
yarn lint
# Type checking
yarn type-check
# Create a new microapp called "music" (following the pattern of existing examples)
yarn microapp create music
This generates:
apps/music-app/
- Standalone Expo Router apppackages/music-microapp/
- Embeddable React componentapps/main-app/app/(tabs)/music.tsx
- Tab integration
Update apps/main-app/app/(tabs)/_layout.tsx
:
<Tabs.Screen
name="music"
options={{
title: "Music",
tabBarIcon: ({ color }) => <TabBarIcon name="music" color={color} />
}}
/>
Standalone Development:
yarn workspace music-app start
Embedded Development:
yarn dev # Main app with all microapps as tabs
Test with existing examples:
yarn workspace ecommerce-app start # Test CLI-generated ecommerce app
yarn workspace banking-app start # Test CLI-generated banking app
yarn workspace social-app start # Test CLI-generated social app
// Navigate between microapps in main app
import { useRouter } from 'expo-router';
function NavigateToOtherApp() {
const router = useRouter();
return (
<Button
title="Go to Banking"
onPress={() => router.push('/(tabs)/banking')}
/>
);
}
All apps support @packages/*
imports:
// Import any microapp component
import EcommerceApp from '@packages/ecommerce-microapp';
import { MicroappConfig } from '@packages/shared-types';
Each app includes proper Metro workspace support:
// Automatic workspace resolution
config.watchFolders = [workspaceRoot];
config.resolver.alias = {
'@packages': path.resolve(workspaceRoot, 'packages'),
};
Core dependencies are shared across all apps:
- React 19.0.0
- React Native 0.79.2
- Expo SDK 53
- Expo Router 5.x
- TypeScript 5.x
// packages/ecommerce-microapp/src/index.tsx (CLI-generated)
export { EcommerceMicroappProvider } from './components/EcommerceMicroappProvider';
export { EcommerceApp } from './screens/EcommerceApp';
export * from './types';
// Default export for easy importing
export { EcommerceApp as default } from './screens/EcommerceApp';
// apps/main-app/app/(tabs)/ecommerce.tsx (CLI-generated)
import React from 'react';
import EcommerceApp from '@packages/ecommerce-microapp';
export default function EcommerceTab() {
return <EcommerceApp microappName="ecommerce" />;
}
// apps/ecommerce-app/app/(tabs)/index.tsx (CLI-generated)
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import EcommerceApp from '@packages/ecommerce-microapp';
export default function HomeScreen() {
return (
<View style={styles.container}>
<Text style={styles.title}>Standalone Ecommerce App</Text>
<Text style={styles.subtitle}>This is the home of your ecommerce microapp</Text>
<View style={styles.microappContainer}>
<EcommerceApp microappName="ecommerce" />
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
},
title: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 8,
textAlign: 'center',
},
subtitle: {
fontSize: 16,
color: '#666',
marginBottom: 20,
textAlign: 'center',
},
microappContainer: {
flex: 1,
backgroundColor: '#f9f9f9',
borderRadius: 10,
overflow: 'hidden',
},
});
- Multiple business units as separate microapps
- Shared authentication and theming
- Independent development teams
- Each tenant gets their own microapp
- Shared core functionality
- Customizable per-tenant features
- Features like Shopping, Banking, Social as separate apps
- Progressive feature rollout
- A/B testing at microapp level
- Core app with pluggable microapps
- Client-specific customizations
- Rapid deployment of new features
Each microapp has its own context provider:
// packages/ecommerce-microapp/src/components/EcommerceMicroappProvider.tsx
export function EcommerceMicroappProvider({ children }) {
const [cartItems, setCartItems] = useState([]);
return (
<EcommerceContext.Provider value={{ cartItems, setCartItems }}>
{children}
</EcommerceContext.Provider>
);
}
Use shared state or URL parameters:
// Navigate with data
router.push({
pathname: '/(tabs)/banking',
params: { fromApp: 'ecommerce', amount: '100' }
});
All microapps support universal deep linking:
myapp://ecommerce/products/123
myapp://banking/transfer?amount=100
myapp://social/profile/user456
# Build all apps
yarn workspace main-app build
yarn workspace ecommerce-app build
yarn workspace banking-app build
Each app can be built independently:
# Main super-app
cd apps/main-app
eas build --platform ios
# Standalone microapp
cd apps/ecommerce-app
eas build --platform android
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature
- Make your changes and add tests
- Commit:
git commit -m 'Add amazing feature'
- Push:
git push origin feature/amazing-feature
- Open a Pull Request
- Use TypeScript for all new code
- Follow the existing file structure conventions
- Add proper error handling and loading states
- Include tests for new microapps
- Update documentation for new features
This project is licensed under the MIT License - see the LICENSE file for details.
- Expo Team for the amazing React Native toolchain
- React Navigation for powering Expo Router
- Yarn Team for workspace support
- The React Native community for inspiration and feedback
- π Report a Bug
- π‘ Request a Feature
- π¬ Start a Discussion
β Star this repo if you found it helpful!
Made with β€οΈ by Alvin Otuya