react-native-skills (vercel-labs/agent-skills)
react-native-skills: lifts a double-tap animation from 'JS-thread Animated' to Reanimated + Gesture Handler (0.7 to 5.0), but on review and optimise tasks it is no better than control and below a one-sentence checklist (4.6 vs 5.0)
24.3 / 30
Lift over no skill: +1.77
Recommended: the total 24.3/30 is at least 22, output quality 4.6 is at least 3.5, and the lift +1.77 is at least +1.0.
SOTA
PassTested with Codex.
Covers Codex, Claude Code
Codex CLI 0.166 (SOTA tier): 18 graded runs. A pass here also covers Claude Code under our tier rule; it says nothing about the second tier.
Scores
Each dimension is 0 to 5 and the six add up to the total out of 30. 5 is better on every dimension. Cost 5 means cheap and fast. Install 5 means easy.
- Trigger reliability
- 5.0
- Lift over no skill
- 3.8
- Output quality
- 4.6
- Token and time cost
- 4.0
- Install and portability
- 3.0
- Safety
- 4.0
Security review
SafeStatic scan: 0 CRITICAL / 3 HIGH / 0 MEDIUM. Manual review: Safe to run in a no-network sandbox (scanner hits explained). A clean scan does not prove a skill safe.
Install
npx skills@latest add vercel-labs/agent-skills --skill react-native-skills
Pinned commit: 1a2c79d4e6c4a2283dc2c614b6538cbe1ed5ca62
Tested: 2026-11-02
What we tested
- Performance review of a feed screen — Review FeedScreen.tsx (an Expo app) for performance problems, most serious first, with what to change for each. Do not change any files.
- Optimise the feed in place — Optimise FeedScreen.tsx for performance. Edit it in place and keep the props and visible behaviour the same. Everything you need is already installed; there is no network.
- Add a Reanimated double-tap heart — Add a heart that pops (scale and fade) over a post's photo when it is double-tapped. Edit FeedScreen.tsx; use what is installed.
Pros
- Lifts the mean score from 2.79 to 4.56 over no skill (+1.77).
- The skill was picked up without being named: Skill file read in 6/6 treatment runs.
- High absolute quality with the skill: 4.56 out of 5.
Cons
- A one-sentence prompt scored 5.0, against 4.56 with the skill (-0.44).
- n=2 per task per arm; differences under about 1 point are noise.
Review
Codex CLI 0.166 (gpt-6-astra, low reasoning) on a dedicated Windows test PC, a fresh temporary project and temporary HOME/TMPDIR/caches per run, skill installed (treatment) or absent (control) or absent with the skill's core requirement squeezed into one sentence appended to the prompt (one-liner group), 2 runs per group per task, network off, /tmp writes blocked. The prompts never mention the skill (except the wording noted below). One Expo feed screen (FeedScreen.tsx) with deliberate problems and a package.json that already lists FlashList, expo-image, Reanimated and Gesture Handler (nothing can be installed). Tasks: review it for performance problems (no edits), optimise it keeping behaviour, and add a heart that pops on double-tap. Prompts do not name any library. The one-liner lists the main rules in one sentence (FlashList, memoised rows with stable callbacks and no inline styles, Pressable and expo-image, Reanimated transform/opacity, gesture handlers).
Three-arm comparison
| Arm | Mean score (0-5) | Tokens per run |
|---|---|---|
| Without the skill | 2.79 | 98k |
| One-sentence prompt | 5.0 | 114k |
| With the skill | 4.56 | 110k |
Measured with Codex CLI over 18 runs, scored by rule-based checks with no LLM judge. Total 24.3 / 30, verdict Recommended.
Verdict: Recommended (24.3 / 30). Source: vercel-labs/agent-skills, skills/react-native-skills, pinned at commit 1a2c79d. Install: npx skills@latest add vercel-labs/agent-skills --skill react-native-skills. Licence: MIT (repo LICENSE).
What it is
The react-native-skills skill (vercel-labs/agent-skills): a rule library for React Native and Expo performance: list virtualisation (FlashList), memoised rows and stable callbacks, Pressable, expo-image, animating transform/opacity with Reanimated on the UI thread, Gesture Handler for taps and a long list of further rules in a rules/ folder (AGENTS.md compiled index).
How we tested
Codex CLI 0.166 (gpt-6-astra, low reasoning) on a dedicated Windows test PC, a fresh temporary project and temporary HOME/TMPDIR/caches per run, skill installed (treatment) or absent (control) or absent with the skill's core requirement squeezed into one sentence appended to the prompt (one-liner group), 2 runs per group per task, network off, /tmp writes blocked. The prompts never mention the skill (except the wording noted below).
One Expo feed screen (FeedScreen.tsx) with deliberate problems and a package.json that already lists FlashList, expo-image, Reanimated and Gesture Handler (nothing can be installed). Tasks: review it for performance problems (no edits), optimise it keeping behaviour, and add a heart that pops on double-tap. Prompts do not name any library. The one-liner lists the main rules in one sentence (FlashList, memoised rows with stable callbacks and no inline styles, Pressable and expo-image, Reanimated transform/opacity, gesture handlers).
- Performance review of a feed screen — Review FeedScreen.tsx (an Expo app) for performance problems, most serious first, with what to change for each. Do not change any files.
- Optimise the feed in place — Optimise FeedScreen.tsx for performance. Edit it in place and keep the props and visible behaviour the same. Everything you need is already installed; there is no network.
- Add a Reanimated double-tap heart — Add a heart that pops (scale and fade) over a post's photo when it is double-tapped. Edit FeedScreen.tsx; use what is installed.
Scoring is programmatic (hidden tests / planted-issue recall / constraint checks / render+OCR where relevant), 0–5 per run. No LLM judge decided any score.
Results
The one-liner given to the third group: "Follow React Native performance practice: virtualise long lists (FlashList), memoise row components with stable callbacks and no inline style objects or per-row heavy work, use Pressable and expo-image, animate only transform and opacity with Reanimated on the UI thread (no JS-driver layout animation), and gesture handlers for taps."
| Task | Control score | One-liner | With skill | Control tokens | One-liner tokens | With-skill tokens | Skill read |
|---|---|---|---|---|---|---|---|
| t1-review | 3.8 | 5.0 | 4.6 | 85k | 92k | 71k | 2/2 |
| t2-optimize | 3.87 | 5.0 | 4.09 | 105k | 140k | 142k | 2/2 |
| t3-double-tap | 0.71 | 5.0 | 5.0 | 103k | 107k | 116k | 2/2 |
Mean score: 2.79 without vs 4.56 with the skill (delta +1.77). Tokens per run: 98k vs 110k (1.12x); time 54s vs 52s. One-liner group: 5.0 (the skill's gain over the one-liner: -0.44; one-liner's own gain over no skill: +2.21); one-liner tokens 114k per run, so the skill costs 0.97x the one-liner.
What happened
- Means: control 2.79, one-liner 5.00, skill 4.56 (n=6 each). The skill beat control on the double-tap task (5.0 vs 0.71): both control runs used the JS-thread
Animated.timingand a plain press handler, ignoring the installed Reanimated and Gesture Handler, while both skill runs used a Gesture Handler tap, shared values and a transform/opacity animation. - On the optimise task the skill did not move the result: treatment 4.09 against control 3.87. All four non-one-liner runs left
TouchableOpacityand the stock RNImagein place and did not use expo-image although it is installed; they fixed memoisation, style hoisting and the avatar list but treated 'keep visible behaviour' as a reason to stay conservative. Both one-liner runs switched to Pressable, expo-image and FlashList and scored 5.0. - On the review task the skill lists most planted problems (9/10 found in 2 runs, missing only the TouchableOpacity point) against 6-8 of 10 for control; one-liner found all 10 in both runs.
- Cost: 110k tokens per run for the skill vs 98k control and 114k one-liner; the skill folder has about 40 files (rule index plus rule files) that were copied into the project in every treatment run (42.7 new files per run on average).
- Skill read in 6/6 treatment runs without being named.
Dimension scores
| Dimension | Score | Why |
|---|---|---|
| 1_output_quality | 4.56 | Mean score 4.56/5 with the skill (programmatic checks, see per-task table). |
| 2_lift_vs_no_skill | 3.77 | +1.77 points vs 2.79 without the skill (n=2 per task; under ~1 point is noise). |
| 3_trigger | 5.0 | Skill file read in 6/6 treatment runs. |
| 4_instructions_portability | 3 | SKILL.md plus a compiled AGENTS.md and about 40 rule files; large for the benefit seen. |
| 5_efficiency | 4 | 1.12x tokens (110k vs 98k per run) and 0.97x time (52s vs 54s). |
| 6_safety_hygiene | 4 | Scanner flags 3 HIGH, all |
Limits of this test
- Rule-based checks on the edited file and on the review text; the app was never built or run.
- Single fixture screen with planted issues, so the one-liner that names the same issues is an upper bound that is unusually well matched to the checks.
- n=2 per cell.
- n = 2 per group per task: differences under about 1 point are noise.
- Rule-based scoring measures what the checks can see; it cannot judge taste or whether a result is the best possible.
Security
See security.md. Scan: 0 CRITICAL / 3 HIGH / 0 MEDIUM. Verdict: safe to run (no-network sandbox). A clean scan does not prove a skill safe.
Bottom line
Useful for steering an agent toward the Reanimated/Gesture Handler stack when adding gestures, and it improves review recall, but it does not make the agent apply the whole rule set when optimising existing code; a sentence naming the libraries did better here. Install it if you add RN animation work often.
Transcript
Run log for react-native-skills: Codex CLI, network off, per-run temp HOME/TMPDIR, one row per graded run. Columns: task, arm-run, score (0-5), tokens, seconds, checks passed, skill files the agent opened. t1-review control-1: score 4.2, tokens 86173, secs 48.3, checks 2/2, opened nothing t1-review control-2: score 3.4, tokens 85790, secs 52.6, checks 2/2, opened nothing t1-review oneliner-1: score 5.0, tokens 98552, secs 59.2, checks 2/2, opened nothing t1-review oneliner-2: score 5.0, tokens 85716, secs 49.5, checks 2/2, opened nothing t1-review treatment-1: score 4.6, tokens 72170, secs 47.4, checks 2/2, opened react-native-skills t1-review treatment-2: score 4.6, tokens 70886, secs 50.8, checks 2/2, opened react-native-skills t2-optimize control-1: score 4.09, tokens 105482, secs 60.5, checks 5/7, opened nothing t2-optimize control-2: score 3.64, tokens 105599, secs 61.9, checks 4/7, opened nothing t2-optimize oneliner-1: score 5.0, tokens 151869, secs 109.3, checks 7/7, opened nothing
18 runs, 3 artifacts
Sample output
SOTA · With the skill: final message (t1-review, run 1, Codex)
Most serious first: 1. **High — Every rendered row sorts the entire feed** ([FeedScreen.tsx:17](C:/Users/<user>/AppData/Local/Temp/asv-react-nati-be075069/work/FeedScreen.tsx:17)). Each row copies and sorts all posts, then searches for its rank. Rendering *v* rows costs roughly O(v × n log n), blocking the JS thread during scrolling. **Change:** compute an ID-to-rank map once with `useMemo([posts])`, then use an O(1) lookup per row. Preserve ranking across all posts when filtering. 2. **High — The avatar strip renders every post immediately** ([line 28](C:/Users/<user>/AppData/Local/Temp/asv-react-nati-be075069/work/FeedScreen.tsx:28)). `ScrollView` with `posts.map()` mounts all avatar views, increasing startup work and image memory as the feed grows. **Change:** use a horizontal `FlatList` or FlashList with stable IDs and a bounded height. The fixed avatar dimensions make layout calculation straightforward. 3. **Medium — Screen rerenders cause avoidable list work** ([line 15](C:/Users/<user>/AppData/Local/Temp/asv-react-nati-be075069/work/FeedScreen.tsx:15)). Filtering creates a new array and `renderItem` creates a new function each render; rows have no memoization boundary. **Change:** memoize filtered posts using `[posts, query]`, extract a `React.memo` row, and stabilize `renderItem` with the correct dependencies. Pass the computed rank and a stable `onOpen`; move static styles into `StyleSheet.create`. Currently, `setQuery` is unused, so typing-related rerenders aren’t present. 4. **Conditional medium — Image payloads may exceed their display needs** ([lines 20](C:/Users/<user>/AppData/Local/Temp/asv-react-nati-be075069/work/FeedScreen.tsx:20) and [30](C:/Users/<user>/AppData/Local/Temp/asv-react-nati-be075069/work/FeedScreen.tsx:30)). Display dimensions don’t guarantee appropriately sized downloads. Original-resolution URLs could add substantial network and decoding cost. **Change:** request compressed thumbnails sized for the display’s pixel density; consider the already-installed `expo-image` for explicit caching and recycling support. The actual source dimensions aren’t available here. 5. **Latent — Width animation uses the JS thread and changes layout every frame** ([line 9](C:/Users/<user>/AppData/Local/Temp/asv-react-nati-be075069/work/FeedScreen.tsx:9)). `grow` is unused, so this has no current animation cost. **Change if activated:** use `scaleX` with the native driver when visual scaling meets the design; it won’t change layout space. Also initialize the value lazily: `useState(() => new Animated.Value(100))`. Static review only; no profiling performed and no files changed.