Agent skill

React Native

by ericrisco in ericrisco/rsc-harness

A skill your agent uses when writing the JS/TS inside a React Native or Expo app — screens, Expo Router navigation, lists, Reanimated gestures, platform forks, offline state, native modules — or…

MITAuto-check passedMobile

Install React Native

skills CLI
$ npx skills add ericrisco/rsc-harness --skill react-native -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install ericrisco/rsc-harness react-native --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/react-native .claude/skills/react-native && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
react-native
GitHub stars
156
Token cost
~3k tokens
SKILL.md length
1,242 words
Files
6 (incl. scripts, references)
Skills in repo
229
Repo updated
First seen
Licence
MIT

At a glance

A skill your agent uses when writing the JS/TS inside a React Native or Expo app — screens, Expo Router navigation, lists, Reanimated gestures, platform forks, offline state, native modules — or…

  • Works in 3 steps: A stable keyExtractor — return a real… → getItemType when rows differ… → A memoized row component with no inline…
  • Writing the JS/TS inside a React Native
  • SKILL.md covers Project shape — pick a router…, Navigation, Lists & performance and Animation & gestures, plus 5 more sections
  • Runs Shell scripts from its folder

What it does

React Native is an agent skill from ericrisco/rsc-harness. Use when writing the JS/TS inside a React Native or Expo app — screens, Expo Router navigation, lists, Reanimated gestures, platform forks, offline state, native modules — or killing jank and render storms. NOT eas build/submit/OTA/config-plugin (that is expo), NOT a Dart app (that is flutter), NOT web React/DOM (that is react or nextjs).

Its SKILL.md is about 3k tokens, which your agent loads only when the skill is triggered. The skill folder holds 8 other files, including scripts and reference files (for example `evals/README.md`, `evals/cases.yaml` and `references/native-modules.md`).

It sits in Mobile, covering Cross-platform mobile apps. It works with Expo, React Native, React and Flutter. The repository describes itself as: Your agent invents things because it has no memory, and can't touch your database because it has no arms. rsc is the meta-harness that gives it both, plus the trade to know the… The licence is MIT.

When your agent uses it

  • Writing the JS/TS inside a React Native
  • Expo app — screens
  • Expo Router navigation
  • Reanimated gestures

Example prompts

  • “/react-native”

Requirements

  • A Bash shell

Workflow steps

3 steps, taken from the first numbered list in SKILL.md.

  1. A stable keyExtractor — return a real id, never the index. Index keys defeat recycling and reorder rows on insert.
  2. getItemType when rows differ structurally (header vs product vs ad). Why: it lets FlashList recycle within a type instead of remeasuring.
  3. A memoized row component with no inline closures or style objects in renderItem.

What it can do on your machine

Read from SKILL.md and the folder at commit 92fde8f. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Ships 1 file in scripts/ (Shell), which the agent can run.

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

React Native loads about 3k tokens when it runs, and up to ~5k if it reads all its reference files. Until then it costs about 90 tokens; SKILL.md has 1,242 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~90
When it runs · the whole SKILL.md, loaded when a task matches
~3k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~5k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.

SKILL.md

The full file from ericrisco/rsc-harness at commit 92fde8f, republished under its MIT licence (© ericrisco). 1,242 words, ~2,991 tokens.

Download SKILL.mdSave it as .claude/skills/react-native/SKILL.md (or your agent's skills folder). This skill also uses 5 other files; get the full folder from GitHub.
name
react-native
description
Use when writing the JS/TS inside a React Native or Expo app — screens, Expo Router navigation, lists, Reanimated gestures, platform forks, offline state, native modules — or killing jank and render storms. NOT eas build/submit/OTA/config-plugin (that is `expo`), NOT a Dart app (that is `flutter`), NOT web React/DOM (that is `react` or `nextjs`).
tags
react-native, expo, mobile, ios, android, navigation, performance
recommends
expo, react, flutter, design, debug, performance
origin
risco

React Native (app code)

Hand-off — the app vs its motion. Animation and gestures in a React Native app — Reanimated worklets on the UI runtime, gesture handoff, sheets, press feedback, haptics — are ../motion-craft/SKILL.md's, whose guidance is platform-agnostic and applies to bare React Native as well as Expo.

You write the code that runs inside the app: render, navigate, animate, list, persist, and author native modules. Mobile is split across two skills by verb — run the verb test before doing anything:

Verb in the requestSkill
render / navigate / animate / list / persist / author-native-module / debug-runtimereact-native (here)
build / submit / update (OTA) / prebuild / config-plugin / eas.json / channel / runtime-version../expo/SKILL.md

Assume the New Architecture is on (Fabric + Turbo Modules). It is mandatory from RN 0.82 / Expo SDK 55 — RN 0.82 (2025-10-08) ignores any disable flag, and SDK 55 is New-Arch-only. SDK 54 (RN 0.81) was the last that could opt out. Never write newArchEnabled: false to dodge a bug; fix the bug. Why: the flag is a no-op on current versions, so the "fix" silently does nothing.

Reference SDK→RN map (accessed 2026-06-02): SDK 53 = RN 0.79, SDK 54 = RN 0.81 (React Compiler GA), SDK 55 = RN 0.83.

Project shape — pick a router first

This is the one real branch at scaffold time:

UseWhen
Expo Router (file-based)New apps, web parity, deep links, typed routes. The recommended default. It is a layer on top of React Navigation; both are Expo-team maintained.
React Navigation v7 (static API)Brownfield apps, native integration, highly bespoke custom transitions where you need imperative control.

Default file tree for an Expo Router app:

text
app/                  # routes — file system IS the navigation
  (auth)/             # group: unauthenticated screens
  (app)/              # group: authenticated screens
    (tabs)/           # nested tab navigator
  _layout.tsx         # root layout + providers
components/           # dumb, reusable UI
features/<domain>/    # feature-scoped screens, hooks, components
lib/                  # clients, query setup, storage, utils

Keep route files thin: a route file wires params and renders a feature component. Put logic in features/. Why: routes get re-mounted by navigation; business logic in them is hard to test and re-runs unexpectedly.

Navigation

Type your routes. With Expo Router, enable typed routes and let useLocalSearchParams<{ id: string }>() carry the contract. Why: deep links and back-stack restoration pass strings you will otherwise misread.

Gate auth at the group layout, declaratively — not imperatively inside an effect:

tsx
// app/(app)/_layout.tsx — Bad: imperative nav in an effect races the first paint
export default function AppLayout() {
  const { user } = useAuth();
  useEffect(() => {
    if (!user) router.replace('/(auth)/sign-in'); // flashes protected UI first
  }, [user]);
  return <Stack />;
}
tsx
// app/(app)/_layout.tsx — Good: redirect before children mount
import { Redirect, Stack } from 'expo-router';
export default function AppLayout() {
  const { user, loading } = useAuth();
  if (loading) return null;          // or a splash
  if (!user) return <Redirect href="/(auth)/sign-in" />;
  return <Stack />;
}

Modals/sheets: declare presentation on the screen, not by pushing a styled full-screen route — <Stack.Screen options={{ presentation: 'modal' }} />. Configure deep links via the scheme + the linking config so a cold-start link resolves to the right nested route, not just the root. A deep link landing on the wrong screen is almost always a group/segment mismatch between the URL and the app/ tree.

Lists & performance

Switch from FlatList to FlashList (Shopify) once a list crosses ~100 items, has variable row heights, or renders images. Why: FlashList recycles views instead of mounting one per row, so memory and scroll jank stay flat as the list grows.

Three things every long list needs:

  1. A stable keyExtractor — return a real id, never the index. Index keys defeat recycling and reorder rows on insert.
  2. getItemType when rows differ structurally (header vs product vs ad). Why: it lets FlashList recycle within a type instead of remeasuring.
  3. A memoized row component with no inline closures or style objects in renderItem.
tsx
// Bad: new fn + new style object every parent render -> every visible row re-renders
<FlashList
  data={items}
  renderItem={({ item }) => (
    <Pressable style={{ padding: 12 }} onPress={() => open(item.id)}>
      <Text>{item.title}</Text>
    </Pressable>
  )}
/>
tsx
// Good: stable refs, memoized row, typed rows
const Row = memo(function Row({ item }: { item: Product }) {
  const open = useOpenProduct();          // stable from context/store
  return (
    <Pressable style={styles.row} onPress={() => open(item.id)}>
      <Text>{item.title}</Text>
    </Pressable>
  );
});

<FlashList
  data={items}
  keyExtractor={(it) => it.id}
  getItemType={(it) => it.kind}
  renderItem={({ item }) => <Row item={item} />}
/>

FlashList caveat: rows can flash into the wrong position for a split second if mounted while entry animations run. Disable entry animations on the initial mount.

React Compiler (GA in SDK 54) auto-memoizes components and reduces manual useMemo/useCallback — but it does not remove the need for virtualization, stable keys, or getItemType. Don't delete your list discipline because the compiler is on. For re-render hunting and profiling, see references/performance-debugging.md.

Animation & gestures

Reanimated worklets run on the UI thread, so animations keep going at 60fps even when JS is busy. Reanimated 4 (stable Oct 2025) requires the New Architecture / RN 0.76+ and adds CSS-style animations while keeping the worklet API. Many teams stay on Reanimated 3 for dependency compatibility — match the project's installed major.

Two rules that fix most gesture bugs:

  • Wrap gesture objects in useMemo. Why: a new gesture object each render reattaches the recognizer and drops in-flight touches.
  • Cross to JS only at the boundary with runOnJS. Why: calling a JS-thread function directly from a worklet crashes; everything inside the worklet must stay on the UI thread.
tsx
// Good: memoized gesture, UI-thread shared value, JS only at the end
const x = useSharedValue(0);
const pan = useMemo(
  () =>
    Gesture.Pan()
      .onUpdate((e) => { x.value = e.translationX; })            // UI thread
      .onEnd(() => { runOnJS(onSwiped)(); x.value = withSpring(0); }), // boundary
  [onSwiped],
);

Use Reanimated 4 CSS animations for simple declarative cases (fades, simple transitions); use worklets for gesture-driven or physics-based motion. Never animate layout on the JS thread when a shared value will do it on the UI thread.

Show full SKILL.md (526 more words)Show less

Platform-conditional code

  • Small forks: Platform.select({ ios: 12, android: 8 }) or Platform.OS === 'ios'.
  • Whole-component forks: Button.ios.tsx / Button.android.tsx — the bundler picks the right one; import ./Button with no extension.
  • Safe area: use react-native-safe-area-context insets, not hardcoded notch padding. Why: insets differ per device and orientation. Palette, type scale and layout intent are not decided here → ../design/SKILL.md.
  • KeyboardAvoidingView behaves differently per platform — padding on iOS, often height or nothing on Android; test both, don't assume the iOS behavior ports.
  • Set the status bar style explicitly per screen via expo-status-bar.

Data & state

  • Server state → TanStack Query. It owns caching, dedupe, retries, and background refetch. Don't hand-roll loading flags in component state.
  • Persistence: MMKV for fast synchronous key/value (auth tokens, flags, small prefs); expo-sqlite + Drizzle for relational or offline-first data. Pick by shape, not habit.
  • Don't reach for Redux by default. Server state lives in Query; the small amount of true client state fits in context or Zustand.
  • Offline-first: persist the Query cache and treat the network as an enhancement, not a precondition.

Native modules — pick the path

PathWhenCost
Plain JS wrapper of an existing libA maintained npm package already bridges the native APINone — do this first
Expo Modules API (Swift/Kotlin)App uses Expo; you want clean Swift/Kotlin, no codegenRequires Expo; least boilerplate
Turbo Module (codegen from TS specs)Bare RN, or you need the RN-default pathCodegen specs + more boilerplate
Nitro ModulesHot path needing max throughputEmerging; weigh maturity

Minimal Expo Module skeleton (definition lives in the module's Swift/Kotlin):

swift
// ios/MyModule.swift
import ExpoModulesCore
public class MyModule: Module {
  public func definition() -> ModuleDefinition {
    Name("MyModule")
    Function("hello") { (name: String) -> String in "Hi \(name)" }
  }
}
ts
// index.ts — typed JS surface
import { requireNativeModule } from 'expo-modules-core';
const MyModule = requireNativeModule('MyModule');
export function hello(name: string): string { return MyModule.hello(name); }

Full Expo Module (Swift + Kotlin + view), the Turbo Module codegen-spec walkthrough, packaging, and autolinking → references/native-modules.md.

Debugging

  • Read Hermes stack traces from the bottom up; the JS frame that matters is usually above the native bridge frames.
  • "Works on iOS, breaks on Android" (or vice versa) → run the platform-divergence checklist in references/performance-debugging.md before guessing.
  • A red screen citing the interop layer is usually an old-architecture lib running under Fabric — update the lib or find a New-Arch-ready replacement; do not disable New Arch.
  • A fault that resists all of the above needs systematic isolation, not more guesses → ../debug/SKILL.md.

Anti-patterns

Anti-patternWhy it hurtsDo instead
FlatList for 5k rows / image feedsMounts a view per row; jank + memory blowupFlashList with getItemType + stable keyExtractor
Inline arrow / style object in renderItemNew ref every render re-renders every visible rowMemoized Row, StyleSheet.create, stable handlers
Gesture object built inline each renderReattaches recognizer, drops in-flight touchesWrap in useMemo keyed on real deps
setState in render pathRender loop / re-render storm on every keystrokeDerive in render or move to an event handler
Imperative router.replace in an effect to gate authFlashes protected UI, races first paint<Redirect> at the group layout
newArchEnabled: false to dodge a New-Arch bugNo-op on RN 0.82+/SDK 55; hides the real causeUpdate the offending lib; fix the bug
Animating layout on the JS threadDrops frames when JS is busyReanimated shared value on the UI thread
Index as list keyBreaks recycling, reorders rows on insertStable domain id
Doing native config / eas.json / OTA hereWrong skill; this is app code../expo/SKILL.md
Hardcoded notch/safe-area paddingWrong on other devices/orientationsreact-native-safe-area-context insets

© ericrisco, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 5 other files (scripts, references) in skills/react-native of ericrisco/rsc-harness.

  • SKILL.md
  • evals/README.md
  • evals/cases.yaml
  • references/native-modules.md
  • references/performance-debugging.md
  • scripts/verify.sh

Open the folder on GitHubat commit 92fde8f

Compare with similar skills

React Native next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

React Native compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
React Native this skillericrisco/rsc-harness156—~3kAutomated safety check: PassMIT
Data Client Setupreactive/data-client2k—~2.2kAutomated safety check: PassApache-2.0
Expo Web To Nativeexpo/skills2.7k—~2.6kAutomated safety check: PassMIT
Cometchat Migrate From Getstreamcometchat/cometchat-skills129—~5.4kAutomated safety check: NotesMIT
Cometchat Migrate From Sendbirdcometchat/cometchat-skills129—~5.2kAutomated safety check: NotesMIT
Olore Rive Latestolorehq/olore103—~465Automated safety check: PassMIT

Similar skills

  • Data Client Setup

    reactive/data-client

    Install and set up @data-client/react or @data-client/vue in a project.

    2k GitHub stars~2.2k tokensUpdated today
    MobileAuto-check passed
  • Official

    Migrate an existing web React app to a native iOS/Android app with Expo.

    2.7k GitHub stars~2.6k tokensUpdated today
    MobileAuto-check passed
  • Cometchat Migrate From Getstream

    cometchat/cometchat-skills

    Migrate an app from Stream (GetStream) Chat to CometChat end-to-end in ONE prompt, on any platform in this pack (React, Angular, React Native/Expo, iOS, Android, Flutter).

    129 GitHub stars~5.4k tokensUpdated 2 days ago
    MobileAuto-check: notes
  • Cometchat Migrate From Sendbird

    cometchat/cometchat-skills

    Migrate an app from Sendbird to CometChat end-to-end in ONE prompt, on any platform in this pack (React, Angular, React Native/Expo, iOS, Android, Flutter).

    129 GitHub stars~5.2k tokensUpdated 2 days ago
    MobileAuto-check: notes
  • Olore Rive Latest

    olorehq/olore

    Local Rive documentation reference (latest). An agent skill from olorehq/olore.

    103 GitHub stars~465 tokensUpdated today
    MobileAuto-check passed
  • Frontend Design

    avibebuilder/claude-prime

    Builds distinctive, production-grade UIs that avoid generic AI aesthetics.

    120 GitHub stars~2.1k tokensUpdated 4 mo ago
    Frontend & DesignAuto-check passed

More from ericrisco/rsc-harness

All 229 skills in this repo
  • Ab Testing

    ericrisco/rsc-harness

    A skill your agent uses when designing or analyzing a controlled experiment — falsifiable hypothesis, sample size from an MDE, reading significance/CI/power, CUPED, or rescuing tests that won't go…

    156 GitHub stars~2.4k tokensUpdated today
    Auto-check passed
  • Accessibility

    ericrisco/rsc-harness

    A skill your agent uses when making a web UI conform to WCAG 2.2 Level AA — axe-core or Lighthouse a11y violations, keyboard operability, focus management, ARIA roles/names/live regions, contrast…

    156 GitHub stars~3.4k tokensUpdated today
    Auto-check passed
  • Ads

    ericrisco/rsc-harness

    A skill your agent uses when running or fixing paid acquisition on Google or Meta — campaign structure (Performance Max, Demand Gen, Search, Advantage+), platform-fit creative, budget/scaling rules…

    156 GitHub stars~2.2k tokensUpdated today
    Auto-check passed
  • Agent Eval

    ericrisco/rsc-harness

    A skill your agent uses when measuring whether an LLM or agent system actually got better and gating merges on it: golden sets, fixing an inflated LLM-as-judge, scoring RAG (faithfulness, contextual…

    156 GitHub stars~3.2k tokensUpdated today
    Auto-check passed
  • AI Media

    ericrisco/rsc-harness

    A skill your agent uses when a creative goal must become a finished media file: pick and order generative-media models per modality — AI voiceover, image-to-video clips, score — then glue them with…

    156 GitHub stars~3.3k tokensUpdated today
    Auto-check passed
  • Analytics

    ericrisco/rsc-harness

    A skill your agent uses when instrumenting product or web analytics — GA4/PostHog SDK wiring, event taxonomy, funnels, double-counted events, consent gating, PII scrubbing.

    156 GitHub stars~2.8k tokensUpdated today
    Auto-check passed

Categories

Questions about React Native

What does React Native do?

A skill your agent uses when writing the JS/TS inside a React Native or Expo app — screens, Expo Router navigation, lists, Reanimated gestures, platform forks, offline state, native modules — or…. React Native is an agent skill from ericrisco/rsc-harness. Use when writing the JS/TS inside a React Native or Expo app — screens, Expo Router navigation, lists, Reanimated gestures, platform forks, offline state, native modules — or killing jank and render storms.

When should I use React Native?

React Native fits situations like: writing the JS/TS inside a React Native; expo app — screens; expo Router navigation; reanimated gestures.

How do I install React Native in Claude Code?

Run `npx skills add ericrisco/rsc-harness --skill react-native -a claude-code`. Or copy the skill folder (skills/react-native in ericrisco/rsc-harness) into .claude/skills/react-native in your project. Claude Code loads it when a task matches its description.

How do I install React Native in Codex?

Run `npx skills add ericrisco/rsc-harness --skill react-native -a codex`. Or copy the skill folder (skills/react-native in ericrisco/rsc-harness) into .agents/skills/react-native in your project. Codex loads it when a task matches its description.

Can I use React Native in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add ericrisco/rsc-harness --skill react-native -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/react-native, .gemini/skills/react-native, .github/skills/react-native and .opencode/skills/react-native in your project.

What does React Native need to run?

Going by SKILL.md and its folder, React Native needs a shell for the scripts in its folder. Our summary lists: A Bash shell.

Does React Native access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is React Native safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.

What licence does React Native use?

React Native is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does React Native use?

About 3k tokens (SKILL.md is roughly 12k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 2k tokens, read only when the agent opens those files.

What are the alternatives to React Native?

Skills that share tags, products or a category with React Native: Data Client Setup (reactive/data-client, 2k stars), Expo Web To Native (expo/skills, 2.7k stars), Cometchat Migrate From Getstream (cometchat/cometchat-skills, 129 stars) and Cometchat Migrate From Sendbird (cometchat/cometchat-skills, 129 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains React Native?

ericrisco (a GitHub user) maintains it in ericrisco/rsc-harness, which has 156 GitHub stars. The repository holds 229 skills in this directory. The repository was last updated on October 6, 2026.

Source: ericrisco/rsc-harness on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.