RemKit is a powerful toolkit that enables micro-frontend architecture for React Native applications! π―
- π Load components remotely - Dynamically fetch and render components from remote URLs
- π§© Modular architecture - Build and deploy components independently
- π Shared dependencies - Efficiently share React and React Native between host and remote apps
- π οΈ Easy CLI - Simple commands to build and serve remote components
- π¦ TypeScript support - Full TypeScript support out of the box
This monorepo contains two main packages:
| Package | Description |
|---|---|
@remkit/react-native π± |
Core library for loading and rendering remote components |
@remkit/cli π οΈ |
CLI tool for building remote component bundles |
- Node.js >= 18
- pnpm >= 9.0.0 (or npm/yarn)
- React Native development environment set up
# Install the core library in your host app
pnpm add @remkit/react-native
# Install the CLI in your remote app (as dev dependency)
pnpm add -D @remkit/cliIn your host app, configure shared dependencies:
// app/_layout.tsx or your root component
import { setup } from "@remkit/react-native";
setup({
shared: {
react: require("react"),
"react-native": require("react-native"),
// Add any other shared dependencies
},
});Create a new React Native component in your remote app:
// remote-app/index.tsx
import { View, Text, StyleSheet } from "react-native";
export default function MyRemoteComponent() {
return (
<View style={styles.container}>
<Text style={styles.text}>Hello from Remote! π</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
},
text: {
fontSize: 24,
fontWeight: "bold",
},
});Initialize RemKit configuration:
# In your remote app directory
npx @remkit/cli initThis creates a remkit.config.json file:
{
"name": "my-remote-app",
"externals": [
"react",
"react-native",
"react/jsx-runtime"
],
"entry": "index.tsx",
"output": "dist"
}# Build the remote component bundle
npx remkit buildThis generates a remoteEntry.js file in the dist directory.
Serve the dist directory using any static file server:
# Using serve (install with: pnpm add -D serve)
npx serve -s dist -l 3000
# Or using http-server
npx http-server dist -p 3000
# Or using Python
python -m http.server 3000 --directory dist// host-app/components/RemoteComponent.tsx
import { remkit } from "@remkit/react-native";
// Create a remote component instance
const RemoteComponent = remkit({
url: "http://localhost:3000/remoteEntry.js", // URL to your remote bundle
});
export default function MyScreen() {
return (
<View>
<RemoteComponent />
</View>
);
}const RemoteComponent = remkit<{ title: string; count: number }>({
url: "http://localhost:3000/remoteEntry.js",
});
export default function MyScreen() {
return (
<RemoteComponent
title="Hello World"
count={42}
/>
);
}host-app/
βββ app/
β βββ _layout.tsx # Setup shared dependencies
β βββ (tabs)/
β βββ explore.tsx # Use remote component
βββ package.json
app/_layout.tsx:
import { setup } from "@remkit/react-native";
setup({
shared: {
react: require("react"),
"react-native": require("react-native"),
},
});app/(tabs)/explore.tsx:
import { remkit } from "@remkit/react-native";
const RemoteMovies = remkit({
url: "http://localhost:3000/remoteEntry.js",
});
export default function ExploreScreen() {
return <RemoteMovies />;
}remote-app/
βββ index.tsx # Remote component
βββ remkit.config.json # RemKit configuration
βββ dist/
β βββ remoteEntry.js # Built bundle (generated)
βββ package.json
index.tsx:
import { View, Text, FlatList } from "react-native";
export default function MoviesList() {
const movies = [
{ id: 1, title: "The Matrix" },
{ id: 2, title: "Inception" },
{ id: 3, title: "Interstellar" },
];
return (
<View>
<Text>My Favorite Movies π¬</Text>
<FlatList
data={movies}
keyExtractor={(item) => item.id.toString()}
renderItem={({ item }) => <Text>{item.title}</Text>}
/>
</View>
);
}remkit.config.json:
{
"name": "movies-remote",
"externals": [
"react",
"react-native",
"react/jsx-runtime"
],
"entry": "index.tsx",
"output": "dist"
}Shared dependencies are libraries that both the host and remote apps use. By marking them as shared:
- β Reduces bundle size
- β Prevents duplicate loading
- β Ensures version consistency
Common shared dependencies:
reactreact-nativereact/jsx-runtimereact-native-gesture-handlerreact-native-safe-area-context
In remkit.config.json, the externals array lists dependencies that should NOT be bundled with the remote component. These are expected to be provided by the host app via the setup() function.
Initialize a new RemKit configuration file.
npx remkit initBuild the remote component bundle.
npx remkit buildOptions:
- Reads configuration from
remkit.config.json - Outputs
remoteEntry.jsto the configured output directory
{
"name": "my-remote-app", // Name of your remote app
"externals": [ // Dependencies to exclude from bundle
"react",
"react-native"
],
"entry": "index.tsx", // Entry point file
"output": "dist" // Output directory
}- π Security: Only load remote components from trusted sources
- π Network: Use HTTPS in production for secure component loading
- β‘ Performance: Cache remote components when possible
- π Debugging: Check browser/device console for loading errors
- π¦ Bundle Size: Keep externals list comprehensive to reduce bundle size
- π Updates: Remote components can be updated without rebuilding the host app
- β Check the URL is accessible
- β Verify CORS is configured correctly
- β Ensure shared dependencies are set up
- β Check browser/device console for errors
- β Ensure TypeScript types match between host and remote
- β
Use generic types when creating remote components:
remkit<YourProps>({...})
- β
Verify
remkit.config.jsonis correct - β Check that entry file exists
- β Ensure all externals are properly configured
Configure shared dependencies for the host app.
setup({
shared: {
[key: string]: unknown;
};
});Create a remote component loader.
remkit<TProps>({
url: string; // URL to remoteEntry.js
}): React.ComponentType<TProps>Contributions are welcome! Feel free to open issues or submit pull requests.
MIT
Made with β€οΈ for the React Native community
β Star this repo if you find it useful!