Skip to content
Development
Agent

react-native-expo

<!-- GENERATED from docs/playbooks/integration/react-native-expo.md by scripts/build-agent-skill.mjs. Do not edit. -->

BOOST
From plugin
crossbind
14832 skills32 agents
Install
$ npx -y skills add crossbind/crossbind --agent claude-code

How it fires

How this agent gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.

Context preview

The summary Claude sees to decide when to auto-load this agent.

<!-- GENERATED from docs/playbooks/integration/react-native-expo.md by scripts/build-agent-skill.mjs. Do not edit. -->

Agent definition

react-native-expo.md

<!-- GENERATED from docs/playbooks/integration/react-native-expo.md by scripts/build-agent-skill.mjs. Do not edit. -->

Integration — React Native + Expo

> Persona 2 sub-playbook. The user's project is an Expo-managed React Native app. Detection: `expo` (or `@expo/cli`) + `react-native` in deps.

Goal

Add crossbind to an Expo RN app so:

  • iOS + Android native C++ compiles and links via Expo's prebuild system.
  • Metro picks up the crossbind loader.
  • Both managed-prebuild and bare workflows are supported.
  • The web build (`expo start --web`, `expo export -p web`) runs the same imports as WebAssembly.

When to use

  • `expo` or `@expo/cli` in deps **and** `react-native` in deps.
  • React Native 0.81 or newer: the bindings keep the JS functions passed as C callbacks in JSI runtime data, which React Native added in 0.81.
  • `app.json` (or `app.config.{js,ts}`) at root.
  • Bare RN (no Expo) → `docs/playbooks/integration/react-native-cli.md`.

Workflow note: Expo Go vs prebuild

crossbind needs **native** code to ship with the app, so it requires:

  • **Expo Prebuild** (`expo prebuild`) — generates `ios/` and `android/` dirs you commit (or regenerate from CI), then native libs link as in bare RN.
  • **EAS Build** (`eas build`) — Expo's cloud builder; works the same as prebuild.
  • **Expo Go** is **not** supported — it ships a fixed native binary; can't link new C++.

If the user is on Expo Go, you must walk them through `expo prebuild` first.

The web build needs neither: Metro compiles the C++ to WebAssembly in crossbind's Docker toolchain, as the Vite plugin does.

Files involved

| File | Role | |------|------| | `package.json` | + `@crossbind/plugin-react-native`, `@crossbind/plugin-react-native-ios-helper` (dependencies), `@crossbind/plugin-metro` (devDependency), optional `@crossbind/port-<name>` | | `metro.config.js` | Wrap Expo's `getDefaultConfig` with `CrossbindMetroPlugin(...)` | | `crossbind.config.{js,mjs}` *(new at root)* | Project-level crossbind config | | `app.json` / `app.config.{js,ts}` | Add `"@crossbind/plugin-react-native"` to `plugins` (it ships an Expo config plugin); ensure `prebuild` is configured | | `ios/`, `android/` | Generated by `expo prebuild`; native link picks up crossbind plugin | | `src/native/` *(if user wraps own C++)* | `.h` + `.cpp` source |

Commands

pnpm add @crossbind/plugin-react-native@beta @crossbind/plugin-react-native-ios-helper@beta
pnpm add -D @crossbind/plugin-metro@beta     # bundling; the RN plugin brings the native toolchain, Metro builds the web wasm
pnpm add -D metro-config     # mergeConfig for metro.config.js, which expo/metro-config does not export
pnpm add @crossbind/port-<name>@beta     # optional

# Add "@crossbind/plugin-react-native" to expo.plugins in app.json before prebuilding

# Generate / regenerate native projects from app config
pnpm expo prebuild      # idempotent; safe to re-run

# iOS pods
cd ios && pod install && cd ..

# Run
pnpm expo run:android
pnpm expo run:ios

# Web: stage the web dependencies, then the dev server builds the wasm on the first page load
pnpm crossbind-metro prepare-web && pnpm expo start --web

# Web export: link the release wasm next to the exported bundle
pnpm crossbind-metro prepare-web && pnpm expo export -p web --clear && pnpm crossbind-metro export-web dist

For EAS:

pnpm eas build --platform ios
pnpm eas build --platform android

EAS picks up `expo prebuild` artifacts automatically; crossbind plugins kick in via the regenerated `Podfile` / `build.gradle`.

Reference config

Mirror `examples/mobile-reactnative-expo/`.

`metro.config.js` (canonical for Expo):

const { getDefaultConfig } = require('expo/metro-config');
const { mergeConfig } = require('metro-config');
const CrossbindMetroPlugin = require('@crossbind/plugin-metro');

const defaultConfig = getDefaultConfig(__dirname);

const config = {
    ...CrossbindMetroPlugin(defaultConfig),
};

module.exports = mergeConfig(defaultConfig, config);

`crossbind.config.mjs`:

import Matrix from '@crossbind/example-lib-prebuilt-matrix/crossbind.config.js';

export default {
    dependencies: [
        Matrix,
    ],
    paths: {
        config: import.meta.url,
    },
};

Web

The web bundle loads the browser build the Vite and webpack plugins make: wasm32, single-threaded unless `crossbind.config.js` or one of its dependencies sets `target.runtime: 'mt'`.

  • `crossbind-metro prepare-web` stages the Conan packages and builds the cargo dependencies the web build needs. It runs before Metro starts, because Metro resolves a `conan:` import against the files it found at startup; the example's `web` and `export:web` scripts run it first.
  • `expo start --web`: the dev server builds the wasm (debug) when the page first asks for `crossbind.js`, and serves `crossbind.js`, `crossbind.wasm` and `crossbind.data.txt`. The build runs inside the dev server, so a cold one holds up every client of that server until it ends. Metro does not watch the C++ sources: after an edit, reload the page, and its request for `crossbind.js` rebuilds what changed.
  • `expo export -p web`: Expo runs nothing after the bundle, so `crossbind-metro export-web <dir>` links the release wasm and copies the same files into the export. Give the export `--clear`: it re-runs the `.h` transforms that write the bridges, which a warm Metro cache skips. With `web.output: 'server'`, Expo writes the client files to `dist/client`; pass that directory.
  • `experiments.baseUrl` is honoured: the bundle asks for the files under it.

Multithread → COOP/COEP

**Not applicable for native RN.** RN runs JS on Hermes/JSC; multithread (`runtime: 'mt'`) uses pthreads via JSI. No browser headers required.

On the web, `runtime: 'mt'` needs a cross-origin isolated page:

  • The dev server sends `Cross-Origin-Opener-Policy: same-origin` and `Cross-Origin-Embedder-Policy: require-corp` itself, on every response.
  • The production host must send them
Read more
Ships withcrossbind

Import C++ and Rust like JavaScript modules (WebAssembly & React Native)

Get the whole plugin

Other agents on crossbind.