React Native quickstart
Install @minip2p/react-native, create a development build, and connect from a component.
@minip2p/react-native requires React Native 0.87 with the New Architecture and
Hermes. It supports iOS 15.1 or newer and Android API 24 or newer.
Install
npm install @minip2p/react-native
Allow local-network connections
On iOS, a direct connection to the desktop on the LAN needs a local-network
usage description. For Expo, merge this into app.json or the equivalent app
config before rebuilding:
{
"expo": {
"ios": {
"infoPlist": {
"NSLocalNetworkUsageDescription": "Connect to a peer on your local network."
}
}
}
}
For a bare React Native app, set NSLocalNetworkUsageDescription in the native
iOS app’s Info.plist instead.
On Android, ensure the host android/app/src/main/AndroidManifest.xml declares
INTERNET. The standard React Native template already includes it:
<uses-permission android:name="android.permission.INTERNET" />
Rebuild the application after installation. Expo Go cannot load minip2p, so an Expo SDK 57 app needs a development build:
npx expo install expo-dev-client
npx expo prebuild
npx expo run:ios
# or: npx expo run:android
Connect to a Node.js listener
useMinip2p owns the endpoint for a component. It starts the endpoint after the
component commits and closes it during cleanup.
First, run the listener from the Node.js quickstart.
Its default listener uses 127.0.0.1, which is reachable only from the desktop
itself. Change listener.mjs to bind the desktop’s LAN address, for example
/ip4/192.168.1.42/udp/4001/quic-v1, then restart it. Copy the complete address
it prints:
/ip4/192.168.1.42/udp/4001/quic-v1/p2p/12D3KooW...
Do not give the phone the original 127.0.0.1 address. It names the phone
itself. Put the phone and desktop on the same LAN, avoid a guest network that
isolates devices, and allow incoming UDP port 4001 through the desktop’s
firewall.
Put this in App.tsx for a project without Expo Router, or in the route
component for an Expo Router project. Replace the placeholder string in
remoteAddress with the complete address printed by the running listener:
import { generateSecretKey, useMinip2p } from "@minip2p/react-native";
import { useCallback, useMemo, useState } from "react";
import { Button, Text, View } from "react-native";
const remoteAddress = "YOUR_LISTENER_ADDRESS_HERE";
export default function App() {
const secretKey = useMemo(() => generateSecretKey(), []);
const createConfig = useCallback(
() => ({
agentVersion: "my-app/0.1.0",
secretKey,
}),
[secretKey]
);
const node = useMinip2p(createConfig);
const [result, setResult] = useState("Not connected");
const connect = useCallback(async () => {
if (node.status !== "running") return;
try {
const connected = await node.endpoint.connectAddr(remoteAddress, {
timeoutMs: 10_000,
});
await node.endpoint.waitPeerReady(connected.peerId, {
timeoutMs: 10_000,
});
const rttMs = await node.endpoint.ping(connected.peerId, {
timeoutMs: 5_000,
});
setResult(`${connected.path.kind} · ${rttMs} ms`);
} catch (error) {
setResult(error instanceof Error ? error.message : String(error));
}
}, [node, remoteAddress]);
if (node.status === "starting") return <Text>Starting minip2p...</Text>;
if (node.status === "failed") return <Text>Failed: {String(node.error)}</Text>;
if (node.status === "closed") return <Text>Endpoint closed</Text>;
return (
<View>
<Text selectable>{node.peerId}</Text>
<Text selectable>{node.listenAddrs.join("\n")}</Text>
<Button title="Connect and ping" onPress={() => void connect()} />
<Text>{result}</Text>
</View>
);
}
Keep createConfig pure and stable for the component lifetime. Store the secret
bytes in protected device storage when the peer needs a stable identity.
Open the screen on the phone, tap “Connect and ping,” and allow local-network
access if iOS prompts. The result shows directDialed and the round-trip time,
such as directDialed · 4 ms.
Prepare mDNS permissions
If the app enables mdns: true, add its Bonjour service type on iOS and the
multicast permissions on Android. Merge the Expo settings into the same app
config, keeping the usage description above. Bare iOS apps add the service to
Info.plist instead.
{
"expo": {
"ios": {
"infoPlist": {
"NSBonjourServices": ["_p2p._udp"]
}
}
}
}<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />Rebuild after changing either file.
Next: Endpoint lifecycle or Networking and events.