Skip to content

Latest commit

 

History

1,092 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

rn-dev-agent

Your agent writes the code. This proves it runs.

A plugin for Claude Code and Codex that turns your coding agent into a React Native development partner — one that reads your running app's component tree, store state, and navigation over the Chrome DevTools Protocol, taps real UI on iOS and Android, and records the evidence that the feature actually works.

CI Docs License: MIT

Get started · Documentation · Benchmarks · Tools

The observe UI live: inspecting a failed flow, checking store state, replaying a saved action, and running the locked E2E suite — all from the browser


See it in 60 seconds

# 1. Install (Claude Code — Codex below)
/plugin marketplace add Lykhoyda/rn-dev-agent
/plugin install rn-dev-agent@rn-dev-agent
/reload-plugins
# 2. Onboard your app — checks the toolchain, writes the project config
/rn-dev-agent:setup

# 3. Ask for a feature. Get it back verified on the simulator.
/rn-dev-agent:rn-feature-dev add a shopping cart with badge, item list, and checkout flow

The agent explores your codebase, designs the change, implements it — then connects to the running app, navigates to the screen, checks the component tree and store state, taps through the flow, and saves the walk as a replayable test. You get working code and the proof.

Codex users: replace /rn-dev-agent:<name> with $rn-dev-agent:<name>. Install steps →


Coding agents ship blind

They are good at writing React Native code and bad at knowing whether it runs. This plugin closes that loop — and the numbers below come from real features built on a real Expo app, not synthetic benchmarks.

Verified, not claimed After implementing, the agent connects over CDP, walks the screen, reads the component tree and store, exercises the interaction, and screenshots the result — before it says "done"
210× faster replays A 3-step wizard that took ~14 min as an interactive walk replays in ~4 s as a saved action. Average session time across the measured features dropped from ~12 min to ~4 min once actions existed
Flows that repair themselves When a testID drifts, the saved action fuzzy-matches the live snapshot, patches its own YAML, and retries. Cosmetic drift is absorbed; genuinely broken product logic is surfaced, never auto-fixed
Minutes, not sessions Simple features land in 3–5 min, complex multi-step flows in 11–25 min. Zero crashes and zero manual interventions across all 35 measured features
iOS and Android, one contract In-tree XCTest and UiAutomator runners give real taps, typing, scrolling, and screenshots — shipped as prebuilt artifacts so first use skips the cold build
Both hosts, full parity Claude Code: 17 slash commands + 11 skills + 6 agents. Codex: 28 native skills (17 workflow + 11 domain). The same 81 MCP tools on both

Full benchmarks and methodology →

Is this for you?

Yes, if you build React Native or Expo apps with a coding agent, you run an iOS Simulator or Android Emulator locally, and you are tired of reviewing changes that were never actually opened. It pays off most on apps with real navigation, real state, and flows you re-walk every session.

Not yet, if you work on web-only React, have no local simulator or emulator, or need an agent pointed at production or store-signed builds — that last one is deliberately out of scope, see Security.


How it works

  /rn-dev-agent:rn-feature-dev "<what you want>"
        │
        ├─ 1 Discover    understand the feature, plan the work
        ├─ 2 Explore     parallel agents map screens, store, navigation, conventions
        ├─ 3 Question    clarify edge cases, error states, data flow
        ├─ 4 Architect   design the change against your existing patterns
        ├─ 5 Implement   store, components, navigation, testIDs
        ├─ 5.5 VERIFY    ◀── CDP health · component tree · store state · interaction · screenshot
        ├─ 6 Review      parallel agents check correctness and RN conventions
        └─ 7 PROOF       ◀── rehearse off camera, persist the action, record a clean replay
                                                            │
                                    working code  +  video  +  screenshots  +  PR body

Phase 5.5 is the one that makes the difference: nothing is reported as working until it has been observed working. Phase 7 rehearses first, so discovery fumbling never ends up in the recording.

The 8-phase pipeline in detail →

Commands

Claude spelling shown. Codex has native parity for every row — use $rn-dev-agent:<name>.

Command Purpose
/rn-dev-agent:rn-feature-dev <desc> Full 8-phase feature pipeline
/rn-dev-agent:test-feature <desc> Test an already-implemented feature; auto-replays a matching saved action
/rn-dev-agent:qa-pr <PR> Device-test a GitHub PR on iOS simulator, Android emulator, and/or physical device
/rn-dev-agent:debug-screen Diagnose and fix a broken screen — parallel evidence from CDP + native logs + component tree
/rn-dev-agent:proof-capture <desc> Rehearsal-gated video + screenshots + generated PR body
/rn-dev-agent:observe Local web UI to watch the agent live — tool-call timeline, device mirror, route/store/component-tree panels, browser-triggered action and E2E replays (guide)
/rn-dev-agent:setup Onboard a project — Claude manages CLAUDE.md, Codex manages AGENTS.md; every project write is previewed
The other 10 commands — actions, regression, build, diagnostics

Actions & regression:

Command Purpose
/rn-dev-agent:list-learned-actions List persisted actions, flows, and feedback memories
/rn-dev-agent:run-action <name> Replay a saved action with auto-repair and structured run records
/rn-dev-agent:lock-e2e <name> Promote a verified action into a frozen, locked e2e regression test (strict no-repair run required)

Build & session:

Command Purpose
/rn-dev-agent:run-workflow <journey> Establish the proven operating sequence before a real device journey
/rn-dev-agent:build-and-test <desc> Build the app (local or EAS), install on device, then test

Diagnostics:

Command Purpose
/rn-dev-agent:doctor Strictly read-only multi-axis plugin/MCP/schema/task/environment diagnosis; recommends but never executes recovery
/rn-dev-agent:check-env Quick environment-readiness check
/rn-dev-agent:nav-graph Extract and inspect the app navigation graph
/rn-dev-agent:check-vercel-rules Report drift between bundled best-practice rules and upstream
/rn-dev-agent:send-feedback Open a GitHub issue with sanitized environment context

Codex exposes exactly these 17 workflow skills plus 11 domain skills; install-time source-command-* migration is deliberately disabled.

The plugin also keeps a gitignored per-project troubleshooting memory (.rn-agent/local/troubleshooting.md) — auto-captured failures and config notes, read at session start.

Actions: the memory of the loop

An action is a saved Maestro flow the agent emits when verification passes — not something you author. Each task then splits in two: replayable actions for the predictable parts (login, navigation, multi-step setup) and live discovery for the part that is actually new. Actions run as prologues to reach a known state before fresh interactive work.

What A saved, parameterised flow with a metadata header and ${KEY} placeholders
Where .rn-agent/actions/<name>.yaml — the plugin's home in your project is .rn-agent/
Create one Run /rn-dev-agent:test-feature <description>; the verified walk is saved automatically
Run one /rn-dev-agent:run-action <name> — the agent also picks actions itself when it needs a known state
Self-repair If a testID changes, cdp_repair_action fuzzy-matches against the live snapshot, patches the YAML, and retries. Small UI drift is absorbed; broken product logic is surfaced, never auto-fixed
Lock it in /rn-dev-agent:lock-e2e freezes a passing action into .rn-agent/e2e/ — locked tests run strict (no repair) via cdp_run_e2e_suite
Why it works Pure scripts don't adapt; a pure LLM re-derives everything every session. Every successful verification adds an action, every drift gets quietly absorbed, every truly broken flow escalates

Full actions guide →

Under the hood

Everything the commands above are built from — expand what you need. The architecture and review phases also apply a bundled set of React Native and React best-practice rules.

81 MCP tools across six families
Family What it's for Examples
Session Fence one worktree, Metro, app, device, runner, Observe UI, and proof run rn_session
CDP React internals via Chrome DevTools Protocol cdp_status, cdp_component_tree, cdp_store_state, cdp_evaluate, cdp_native_errors, cdp_navigate, collect_logs
Device Native interaction with the simulator/emulator device_find, device_press, device_fill, device_screenshot, device_pick_date, device_batch
Actions Record / replay / self-repair persistent flows, including fail-stop login cdp_login_prologue, cdp_run_action, cdp_repair_action, cdp_record_test_save_as_action, cdp_lock_e2e_test, cdp_run_e2e_suite
Testing E2E replay and PR-ready proof proof_step, cross_platform_verify, maestro_run, maestro_test_all (cdp_auto_login is legacy per-call recovery, not a failed-login fallback or PR proof)
Macro-Asserts State-assertive replays — internal state, not pixels expect_redux, expect_route, expect_visible_by_testid, expect_text

The committed tool surface is asserted in CI against a golden registry (packages/rn-dev-agent-core/test/fixtures/tool-registry.json), so tool additions and removals can't silently drift. Full tool reference →

Reliability baked into the tool layer
  • Self-healing taps — a stale @ref is re-bound by identity (testID/label/role, unique match only). Opt out with RN_SELF_HEAL=0. A dispatched tap is never replayed because its effect is uncertain: on iOS an unchanged tap stays a success carrying meta.noUiChange, and on Android a tap whose effect cannot be observed fails (INTERACTION_EFFECT_UNVERIFIED, mutation: possible) rather than reporting success.
  • Quiescence bypass (iOS) — XCTest's private idle-wait is disabled by default so apps with Reanimated or looping animations can't hang queries. Opt out with RN_QUIESCENCE_BYPASS=0.
  • Engine pinning — setup installs attested maestro-runner 1.1.24 in the versioned pin-cache (floor >= 1.1.24) and verifies its checksum fail-closed; replay and /doctor refuse missing, older, or unattested engines.
  • Degraded-runtime detection — when taps succeed but the app doesn't respond, results carry a "simulator likely wedged, reboot it" hint instead of a misleading "element not found."
Six specialized agents

Each runs a focused protocol: tester, PR QA, debugger, code explorer, architect, reviewer.

Note: rn-tester, rn-pr-qa, and rn-debugger need MCP tools, which don't propagate to spawned subagents — use /rn-dev-agent:test-feature, /rn-dev-agent:qa-pr, and /rn-dev-agent:debug-screen, which run the protocols inline (GH #31).

Architecture
Claude Code / Codex
  ├── Host workflows + shared domain knowledge
  │   Claude: commands/agents · Codex: explicit workflow/domain skills
  │
  ├── Fenced session authority ── worktree → Metro → app → device
  │
  ├── MCP Server (CDP Bridge) ─── WebSocket → bound Metro → Hermes CDP
  │   Tools: component tree, store state, profiling, network,
  │   interaction, recording, self-healing replay
  │
  └── Device interaction
      ├── iOS    → in-tree rn-fast-runner (XCTest /command HTTP)
      └── Android → in-tree rn-android-runner (UiAutomator instrumentation)
          │                         │
     iOS Simulator           Android Emulator

      Device lifecycle (boot / install / launch): xcrun simctl + adb
      E2E test execution: maestro-runner 1.1.24 (pin-cache only)

Architecture details →


Install

Claude Code

/plugin marketplace add Lykhoyda/rn-dev-agent
/plugin install rn-dev-agent@rn-dev-agent
/reload-plugins

Local checkout: claude --plugin-dir /path/to/rn-dev-agent (the root .claude-plugin/marketplace.json resolves the plugin package from packages/claude-plugin/).

Codex

codex plugin marketplace add Lykhoyda/rn-dev-agent
codex plugin add rn-dev-agent@rn-dev-agent

Local checkout: register the package directory /path/to/rn-dev-agent/packages/codex-plugin — not the repository root. The Codex package is self-contained (bundled MCP runtime, native runner sources, helpers, and runner manifest) and loads the same cdp MCP server from its .mcp.json. Codex does not load Claude Code hooks — No plugin hooks is expected. Codex 0.145.0 is the live-refresh floor; older hosts are restart-only. An external CLI or manual plugin change always requires exiting and relaunching Codex.

Then set up your project

cd /path/to/your-rn-app

Claude: /rn-dev-agent:setup
Codex:  $rn-dev-agent:setup

Claude setup manages CLAUDE.md; Codex setup manages an idempotent sentinel-bounded AGENTS.md block, runs strictly read-only package/recovery diagnostics first, and previews every later project write for consent. Full setup guide →

What setup checks, and what it fixes for you

Claude hooks and normal runtime use can perform the automatic handling below; Codex setup keeps recovery diagnosis read-only and prints the exact commands for you to confirm and run.

Check Required Automatic handling
Node.js ≥ 24 Yes No
CDP bridge deps Yes Yes
rn-fast-runner (iOS) iOS targets only Prebuilt artifact on releases; one-time xcodebuild build-for-testing fallback
rn-android-runner (Android) Android targets only Prebuilt artifact on releases; Gradle build fallback on first use
maestro-runner Yes Yes (pin-cache engine >= 1.1.24, attested 1.1.24 checksum-verified)
iOS Simulator / Android Emulator One platform No
Session-bound Metro Yes Project integration starts or validates it through literal pnpm ios / pnpm android
CDP connection Yes rn_session owns the binding; cdp_status is passive and cdp_connect pins the exact target
ffmpeg Optional (proof videos; required for strict iOS proof) Yes
idb + idb-companion Optional (smooth observe-UI mirroring) Yes

Claude automation failures and Codex missing prerequisites are reported with step-by-step manual instructions.

Prebuilt runners: on a released version, the device runners install from a verified prebuilt artifact (SHA-256-checked local cache, then the GitHub Release asset for your exact plugin version), so the first device_snapshot action=open skips the cold build. Resolution is fail-open — offline, a checksum mismatch, or a dev checkout falls back transparently to the on-machine build (the host's doctor workflow reports which one you got). Force local builds with RN_RUNNER_BUILD=local.

What your app needs

Most apps need zero setup — the plugin reads the React fiber tree directly via Metro's CDP endpoint. Redux is auto-detected.

Zustand stores — one line in your app entry (details):

if (__DEV__) {
  global.__ZUSTAND_STORES__ = { auth: useAuthStore, cart: useCartStore };
}

testIDs — add to interactive elements for reliable queries:

<Pressable testID="checkout-button" onPress={handleCheckout}>
  <Text testID="cart-badge">{itemCount}</Text>
</Pressable>

Benchmarks

35 features completed on the public test app.

Complexity Time Crashes Manual interventions
Simple (search, toggle, store) 3–5 min 0 0
Medium (forms, charts, lists) 5–10 min 0 0
Complex (3-step wizard, onboarding) 11–25 min 0 0

Libraries verified end-to-end: react-hook-form, zod, @tanstack/react-query, @gorhom/bottom-sheet, @shopify/flash-list, zustand, react-native-svg, expo-notifications, react-native-reanimated, react-native-gesture-handler, expo-haptics

Full benchmarks →

Security

The cdp_evaluate tool runs arbitrary JavaScript in your app's Hermes runtime with full access to the component tree, store state, AsyncStorage, and any in-memory secrets. This is intentional — runtime introspection is what makes the plugin useful — but it means only run this plugin against apps where you trust the agent's prompts.

  • Local dev environments only. Do not point the plugin at production builds, store-signed apps, or any app holding real user data.
  • Treat the agent like a developer with shell access to your laptop. Any prompt that reaches cdp_evaluate (directly or through another tool) can read or mutate your app's runtime state.
  • Use the fenced session as CDP authority. rn_session binds the intended worktree, Metro, app, and device; cdp_targets may explain ambient Hermes processes but never authorizes selecting one. See Parallel session authority.

The plugin makes no attempt to sandbox cdp_evaluate. If you need that, gate tool access through your agent's permission prompts rather than trusting the tool layer.

What the observability UI and the local evidence store record

The observability UI (/rn-dev-agent:observe) binds to 127.0.0.1 only and rejects cross-origin requests via Host-header + Sec-Fetch-Site checks. It is read-only except for two deliberate, CSRF-token-gated endpoints that trigger action and locked-E2E replays. Tool arguments are deep-redacted fail-closed before reaching the stream and typed fill text is never streamed verbatim (see the security posture for what is redacted and what stays visible), and the recorder keeps only a small bounded in-memory ring buffer — the event stream itself never touches disk (action RunRecords and locked-E2E run output follow the session state directory: fenced sessions use their session-private runtime state, while an unfenced process uses .rn-agent/state/ for actions and .rn-agent/state/e2e-runs/ for E2E history; .rn-agent/e2e/ contains the locked test definitions).

Meaningful tool failures and immediate successful retries also feed a separate, local-only evidence store at ~/.claude/rn-agent/experience/patterns.jsonl. Records are sanitized before writing, deduplicated, capped at 500 patterns, and retained for 14 days; ordinary successful calls are never stored. Runner failures may also retain up to five sanitized diagnostics bundles alongside that store, each capped at 200 typed lifecycle events and 256 KB for reviewed feedback or an explicit collect_logs export. From an installed plugin package, inspect the read-only trend report with node <plugin-package>/rn-dev-agent-core/dist/experience-trends.js --since <previous-report-ISO-timestamp> (omit --since for the last 24 hours). The command never updates the evidence store or uploads data.

Troubleshooting

Problem Solution
"Metro not found" Inspect rn_session(action="status"), then use literal pnpm ios or pnpm android through the confirmed project integration
"No Hermes target" Open the bound app, inspect passive cdp_status, then use cdp_connect to pin the exact signed target
CDP rejected (1006) Close React Native DevTools, Flipper, or Chrome DevTools
Zustand store error Add global.__ZUSTAND_STORES__ (setup)
Plugin not detected (Claude) /plugin install rn-dev-agent@rn-dev-agent then /reload-plugins
Subagent says "MCP tools unavailable" Never spawn rn-tester/rn-pr-qa/rn-debugger via the Task tool — use /rn-dev-agent:test-feature, /rn-dev-agent:qa-pr, or /rn-dev-agent:debug-screen instead (GH #31)
More: host recovery, device runners, wedged simulators
Problem Solution
Plugin not detected (Codex) Inspect with codex plugin list --json and /mcp verbose; user-confirm codex plugin add rn-dev-agent@rn-dev-agent --json, then relaunch after external changes
Codex tools fail after upgrade /mcp verbose inspects only. Relaunch Codex for external/manual changes or legacy hosts; never kill another host's bridge
Blank white screen after many reloads NativeWind stylesheet corruption after 5+ cdp_reload cycles — kill and restart Metro, relaunch the app
device_scroll times out on Reanimated screens A waitForIdle round-trip can deadlock against Reanimated worklets; scroll routes through the in-tree runner's HID synthesis instead. Ensure the runner is healthy via the device session
Legacy AgentDeviceRunner re-appears on iOS Stale ~/.agent-device/daemon.json respawns the upstream runner. The plugin terminates stale processes at session-open (opt out: RN_DEVICE_KILL_LEGACY=0); manual cleanup: pkill -f AgentDeviceRunner && rm -f ~/.agent-device/daemon.{json,lock}
iOS "rn-fast-runner did not become ready" The runner self-build timed out or failed. In a source checkout, pre-build once: cd packages/rn-fast-runner/RnFastRunner && xcodebuild build-for-testing -project RnFastRunner.xcodeproj -scheme RnFastRunner -destination "platform=iOS Simulator,id=<UDID>" -derivedDataPath ../build/DerivedData
device_fill reports TEXT_ENTRY_UNVERIFIED A fill attempt ran, but stable exact read-back could not prove the requested value. Check meta.mutation: retry from a fresh snapshot only when it is none; for observed or possible, read and rebind the field before correcting it so a blind retry cannot double-type
Need an intentional coordinate tap Use device_press({x, y}) (or a batch press step with x/y). With a visible iOS keyboard, raw coordinates are geometry-unknown: the keyboard is proven hidden before the one tap. Prefer fresh refs for normal UI controls
Native logs include another device/app Reopen the exact device session. collect_logs pins Android to that session's adb serial and iOS to that simulator plus the current target-app PID; it fails closed when exact scope cannot be resolved. When the probe runs and proves the app is not running, the stream stays pinned to that simulator and reports scopes.native_ios.process = app-not-running-device-scoped so a crash trail is still captured
Want XCTest's stock idle-waits back Kill the running runner (pkill -f RnFastRunnerUITests), set RN_QUIESCENCE_BYPASS=0, reopen the device session, and inspect the next device result's meta.quiescenceBypass
Seeing meta.reResolved / meta.noUiChange Stale-ref healing at work; meta.noUiChange means the iOS tap was dispatched but changed nothing. Disable ref healing with RN_SELF_HEAL=0 (retryIfNoChange is a deprecated no-op — taps are never replayed)

Full troubleshooting guide →

Keeping up to date

Enable auto-update in the host plugin manager, or update manually:

Claude: /plugin update rn-dev-agent@rn-dev-agent
        /reload-plugins
Codex:  codex plugin marketplace upgrade rn-dev-agent
        codex plugin add rn-dev-agent@rn-dev-agent --json
        # relaunch after this external mutation

Release notes: GitHub Releases · core changelog

Development — building from source

This is a Yarn workspace monorepo:

Package What it is
packages/rn-dev-agent-core The MCP server (CDP bridge, device control, actions, testing) — all TypeScript source and tests
packages/claude-plugin Claude Code plugin package — manifest, commands, agents, skills, hooks, MCP registration
packages/codex-plugin Codex plugin package — self-contained with bundled runtime
packages/shared-agent-knowledge Source of truth both host packages are generated from
packages/rn-fast-runner In-tree iOS XCTest device runner
packages/rn-android-runner In-tree Android UiAutomator device runner
apps/docs-site Astro Starlight docs → lykhoyda.github.io/rn-dev-agent
git clone https://github.com/Lykhoyda/rn-dev-agent.git
cd rn-dev-agent
corepack enable
corepack yarn install --immutable
corepack yarn build:host-runtimes   # builds core + generates both host packages

Run locally: claude --plugin-dir /path/to/rn-dev-agent (Claude Code) or register packages/codex-plugin (Codex).

corepack yarn test          # complete unit-test suite
corepack yarn lint          # oxlint
corepack yarn format:check  # oxfmt

Versioning uses changesets; every tool-surface change must update the golden registry (node scripts/update-tool-registry.mjs).


Stop taking your agent's word for it.

Install it in 60 seconds →

Read the docs · Star the repo · Report a bug or run /rn-dev-agent:send-feedback

Free · open source · MIT

About

Claude Code | Codex plugin for React Native — explores codebases, designs architecture, implements features and QA the code in provable way

Topics

Resources

Security policy

Stars

11 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages