Skip to content

gstcarv/react-native-remkit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

9 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸš€ React Native RemKit

Build modular React Native apps with remote components! 🎨

TypeScript React Native Expo


✨ What is RemKit?

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

πŸ“¦ Packages

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

πŸš€ Getting Started

Prerequisites

  • Node.js >= 18
  • pnpm >= 9.0.0 (or npm/yarn)
  • React Native development environment set up

Installation

1. Install the packages

# 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/cli

2. Setup the host app

In 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
  },
});

3. Create a remote component

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",
  },
});

4. Configure the remote app

Initialize RemKit configuration:

# In your remote app directory
npx @remkit/cli init

This creates a remkit.config.json file:

{
  "name": "my-remote-app",
  "externals": [
    "react",
    "react-native",
    "react/jsx-runtime"
  ],
  "entry": "index.tsx",
  "output": "dist"
}

5. Build the remote component

# Build the remote component bundle
npx remkit build

This generates a remoteEntry.js file in the dist directory.

6. Serve the remote component

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

7. Use the remote component in your host app

// 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>
  );
}

8. Pass props to remote components

const RemoteComponent = remkit<{ title: string; count: number }>({
  url: "http://localhost:3000/remoteEntry.js",
});

export default function MyScreen() {
  return (
    <RemoteComponent 
      title="Hello World" 
      count={42} 
    />
  );
}

πŸ“š Complete Example

Host App Structure

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 Structure

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"
}

🎯 Key Concepts

Shared Dependencies

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:

  • react
  • react-native
  • react/jsx-runtime
  • react-native-gesture-handler
  • react-native-safe-area-context

External Dependencies

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.


πŸ› οΈ CLI Commands

remkit init

Initialize a new RemKit configuration file.

npx remkit init

remkit build

Build the remote component bundle.

npx remkit build

Options:

  • Reads configuration from remkit.config.json
  • Outputs remoteEntry.js to the configured output directory

πŸ”§ Configuration

remkit.config.json

{
  "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
}

πŸ’‘ Tips & Best Practices

  1. πŸ”’ Security: Only load remote components from trusted sources
  2. 🌐 Network: Use HTTPS in production for secure component loading
  3. ⚑ Performance: Cache remote components when possible
  4. πŸ› Debugging: Check browser/device console for loading errors
  5. πŸ“¦ Bundle Size: Keep externals list comprehensive to reduce bundle size
  6. πŸ”„ Updates: Remote components can be updated without rebuilding the host app

πŸ› Troubleshooting

Component not loading?

  • βœ… Check the URL is accessible
  • βœ… Verify CORS is configured correctly
  • βœ… Ensure shared dependencies are set up
  • βœ… Check browser/device console for errors

Type errors?

  • βœ… Ensure TypeScript types match between host and remote
  • βœ… Use generic types when creating remote components: remkit<YourProps>({...})

Build errors?

  • βœ… Verify remkit.config.json is correct
  • βœ… Check that entry file exists
  • βœ… Ensure all externals are properly configured

πŸ“– API Reference

setup(options)

Configure shared dependencies for the host app.

setup({
  shared: {
    [key: string]: unknown;
  };
});

remkit<TProps>(options)

Create a remote component loader.

remkit<TProps>({
  url: string;  // URL to remoteEntry.js
}): React.ComponentType<TProps>

🀝 Contributing

Contributions are welcome! Feel free to open issues or submit pull requests.


πŸ“„ License

MIT


Made with ❀️ for the React Native community

⭐ Star this repo if you find it useful!

About

Remote components support for react-native projects

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published