react-native-skills (vercel-labs/agent-skills)
React Native와 Expo 모범 사례를 목록 성능, 애니메이션, 내비게이션, 네이티브 모듈에 적용합니다.
react-native-skills: 더블 탭 애니메이션을 'JS 스레드 Animated'에서 Reanimated + Gesture Handler로 끌어올렸지만(0.7에서 5.0으로), 리뷰·최적화 과제에서는 대조군보다 낫지 않고 한 문장 체크리스트보다도 낮습니다(4.6 vs 5.0)
Codex CLI · gpt-6-astra
24.3 / 30
스킬 없이 대비 향상폭: +1.77 · 추천 · 18회 실행
추천: 총점 24.3/30이 22점 이상, 출력 품질 4.6가 3.5 이상, 향상폭 +1.77가 +1.0 이상입니다.
SOTA
통과Codex로 테스트
커버 대상 Codex, Claude Code
Codex CLI 0.166 (SOTA 티어): 채점된 실행 18회. 여기서 통과하면 티어 규칙에 따라 Claude Code도 커버되지만, 두 번째 티어에 대해서는 아무것도 말해주지 않습니다.
점수
각 차원은 0~5점이며 여섯 차원을 더하면 30점 만점의 총점이 됩니다. 모든 차원에서 5가 가장 좋습니다. 비용 5는 저렴하고 빠름, 설치 5는 쉬움을 뜻합니다.
- 트리거 신뢰도
- 5.0
- 스킬 없이 대비 향상폭
- 3.8
- 출력 품질
- 4.6
- 토큰 및 시간 비용
- 4.0
- 설치 및 이식성
- 3.0
- 안전성
- 4.0
보안 리뷰
안전정적 스캔: CRITICAL 0 / HIGH 3 / MEDIUM 0. 수동 검토: 네트워크가 차단된 샌드박스에서 실행 안전(스캐너 지적 사항은 설명됨). 스캔이 깨끗하다고 해서 스킬이 안전하다는 증거는 아닙니다.
설치
npx skills@latest add vercel-labs/agent-skills --skill react-native-skills
고정 커밋: 1a2c79d4e6c4a2283dc2c614b6538cbe1ed5ca62
테스트일: 2026-11-02
테스트한 과제
- 피드 화면 성능 리뷰 — FeedScreen.tsx(Expo 앱)의 성능 문제를 심각한 순서대로 리뷰하고, 각 문제마다 무엇을 바꿀지 알려 주세요. 파일은 수정하지 마세요.
- 피드 최적화(제자리 수정) — FeedScreen.tsx를 성능 위주로 최적화하세요. 파일을 직접 수정하되 props와 눈에 보이는 동작은 그대로 유지하세요. 필요한 것은 모두 설치되어 있고 네트워크는 없습니다.
- Reanimated 더블 탭 하트 추가 — 게시물 사진을 더블 탭하면 사진 위에서 하트가 튀어오르도록(scale과 fade) 추가하세요. FeedScreen.tsx를 수정하고, 설치된 것만 사용하세요.
장점
- 스킬 없이보다 평균 점수를 2.79에서 4.56으로 끌어올렸습니다(+1.77).
- 스킬 이름을 언급하지 않았는데도 적용되었습니다. 스킬 사용군 실행 6/6회에서 스킬 파일을 읽었습니다.
- 스킬 사용 시 높은 절대 품질: 4.56/5.
단점
- 한 문장 프롬프트는 5.0점, 스킬 사용은 4.56점(-0.44).
- 과제·그룹당 n=2이며, 약 1점 미만의 차이는 노이즈입니다.
리뷰
Codex CLI 0.166 (gpt-6-astra, low reasoning)을 전용 Windows 테스트 PC에서 실행했고, 실행마다 새 임시 프로젝트와 임시 HOME/TMPDIR/캐시를 사용했습니다. 스킬 설치(스킬 사용군), 미설치(대조군), 미설치 상태에서 스킬의 핵심 요구사항만 한 문장으로 압축해 프롬프트에 덧붙인 경우(한 문장 프롬프트군)로 나눴으며, 과제·그룹당 2회씩 실행했습니다. 네트워크는 끄고 /tmp 쓰기는 차단했습니다. 프롬프트에는 스킬 이름을 언급하지 않았습니다(아래에 적은 경우 제외). 의도적으로 문제를 심어 둔 Expo 피드 화면 하나(FeedScreen.tsx)와, FlashList, expo-image, Reanimated, Gesture Handler가 이미 나열된 package.json을 준비했습니다(추가 설치는 불가). 과제는 성능 문제를 리뷰하고(수정 금지), 동작을 유지한 채 최적화하고, 더블 탭 시 터지는 하트를 추가하는 것입니다. 프롬프트에는 어떤 라이브러리 이름도 쓰지 않았습니다. 한 문장 프롬프트는 핵심 규칙을 한 문장으로 나열합니다(FlashList, 안정적인 콜백과 인라인 스타일이 없는 메모화된 행, Pressable과 expo-image, Reanimated transform/opacity, 제스처 핸들러).
3개 그룹 비교
| 그룹 | 평균 점수 (0-5) | 실행당 토큰 |
|---|---|---|
| 스킬 없음 | 2.79 | 98k |
| 한 문장 프롬프트 | 5.0 | 114k |
| 스킬 사용 | 4.56 | 110k |
Codex CLI에서 18회 실행해 측정했고, LLM 심사 없이 규칙 기반 검사로 채점했습니다. 총점 24.3 / 30, 판정 추천.
판정: 추천 (24.3 / 30). 출처: vercel-labs/agent-skills, skills/react-native-skills, 커밋 1a2c79d에 고정. 설치: npx skills@latest add vercel-labs/agent-skills --skill react-native-skills. 라이선스: MIT(저장소 LICENSE).
무엇인가
vercel-labs/agent-skills의 react-native-skills 스킬입니다. React Native와 Expo 성능을 위한 규칙 라이브러리입니다. 리스트 가상화(FlashList), 메모이제이션된 행과 안정적인 콜백, Pressable, expo-image, UI 스레드에서 Reanimated로 transform/opacity 애니메이션, 탭 처리를 위한 Gesture Handler, 그리고 rules/ 폴더에 담긴 다양한 추가 규칙(AGENTS.md에 색인을 모아 둠)을 제공합니다.
테스트 방법
Codex CLI 0.166(gpt-6-astra, 낮은 추론)을 전용 Windows 테스트 PC에서 실행했고, 실행마다 새 임시 프로젝트와 임시 HOME/TMPDIR/캐시를 사용했습니다. 스킬을 설치한 스킬 사용군, 스킬이 없는 대조군, 스킬 없이 핵심 요구사항을 한 문장으로 압축해 프롬프트 끝에 붙인 한 문장 프롬프트군으로 나눴으며, 작업·군당 2회 실행, 네트워크 차단, /tmp 쓰기 차단 조건이었습니다. 프롬프트에는 스킬 이름을 전혀 언급하지 않았습니다(아래에 적은 표현 제외).
의도적인 문제가 있는 Expo 피드 화면(FeedScreen.tsx) 하나와, 이미 FlashList, expo-image, Reanimated, Gesture Handler가 나열된 package.json을 사용했습니다(아무것도 설치할 수 없음). 작업은 성능 문제 리뷰(수정 없음), 동작을 유지한 채 최적화, 더블 탭에 터지는 하트 추가입니다. 프롬프트에는 어떤 라이브러리 이름도 나오지 않습니다. 한 문장 프롬프트는 핵심 규칙을 한 문장으로 나열합니다(FlashList, 안정적인 콜백과 인라인 스타일 없는 메모이제이션 행, Pressable과 expo-image, Reanimated transform/opacity, 제스처 핸들러).
- 피드 화면 성능 리뷰 — FeedScreen.tsx(Expo 앱)의 성능 문제를 가장 심각한 것부터 검토하고, 각 문제에 무엇을 바꿀지 적으세요. 파일은 변경하지 마세요.
- 피드 최적화 — FeedScreen.tsx를 성능 중심으로 최적화하세요. 파일을 그 자리에서 편집하되 props와 눈에 보이는 동작은 그대로 유지하세요. 필요한 것은 모두 설치되어 있고 네트워크는 없습니다.
- Reanimated 더블 탭 하트 추가 — 게시물 사진을 더블 탭하면 사진 위에서 하트가 튀어나오도록(scale과 fade) 추가하세요. FeedScreen.tsx를 편집하고, 설치된 것을 사용하세요.
채점은 프로그램 방식(숨은 테스트/심어 둔 문제 탐지/제약 조건 검사/해당되는 경우 렌더링+OCR)으로 진행하며 실행당 0~5점입니다. 어떤 점수도 LLM 심사자가 결정하지 않았습니다.
결과
세 번째 군에 제공한 한 문장 프롬프트: "React Native 성능 관행을 따르세요. 긴 목록은 가상화하고(FlashList), 인라인 스타일 객체나 행마다 무거운 작업 없이 안정적인 콜백으로 행 컴포넌트를 메모이제이션하고, Pressable과 expo-image를 사용하며, UI 스레드에서 Reanimated로 transform과 opacity만 애니메이션하고(JS 드라이버 레이아웃 애니메이션 금지), 탭에는 제스처 핸들러를 사용하세요."
| 작업 | 대조군 점수 | 한 문장 프롬프트 | 스킬 사용 | 대조군 토큰 | 한 문장 토큰 | 스킬 사용 토큰 | 스킬 읽음 |
|---|---|---|---|---|---|---|---|
| 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 |
평균 점수: 스킬 없음 2.79 vs 스킬 사용 4.56(델타 +1.77). 실행당 토큰: 98k vs 110k(1.12배), 시간 54초 vs 52초. 한 문장 프롬프트군: 5.0(한 문장 프롬프트 대비 스킬의 이득: -0.44, 스킬 없음 대비 한 문장 프롬프트의 이득: +2.21). 한 문장 프롬프트는 실행당 114k 토큰이므로 스킬 비용은 한 문장 프롬프트의 0.97배입니다.
무슨 일이 있었나
- 평균: 대조군 2.79, 한 문장 5.00, 스킬 4.56(각 6회). 더블 탭 작업에서 스킬이 대조군을 이겼습니다(5.0 vs 0.71). 대조군 두 실행 모두 JS 스레드의
Animated.timing과 일반 press 핸들러를 써서 설치된 Reanimated와 Gesture Handler를 무시했고, 스킬 사용군 두 실행은 Gesture Handler 탭, 공유 값, transform/opacity 애니메이션을 사용했습니다. - 최적화 작업에서는 스킬이 결과를 바꾸지 못했습니다. 스킬 사용군 4.09 vs 대조군 3.87. 한 문장 프롬프트가 아닌 네 실행 모두
TouchableOpacity와 기본 RNImage를 그대로 두었고, expo-image가 설치되어 있는데도 쓰지 않았습니다. 메모이제이션, 스타일 호이스팅, 아바타 목록은 고쳤지만 '눈에 보이는 동작 유지'를 보수적으로 남는 이유로 삼았습니다. 한 문장 프롬프트 두 실행은 모두 Pressable, expo-image, FlashList로 바꾸고 5.0을 받았습니다. - 리뷰 작업에서 스킬은 심어 둔 문제 대부분을 나열했습니다(두 실행에서 10개 중 9개 발견, TouchableOpacity 항목만 누락). 대조군은 10개 중 6~8개였고, 한 문장 프롬프트는 두 실행 모두 10개를 모두 찾았습니다.
- 비용: 실행당 스킬 110k 토큰, 대조군 98k, 한 문장 114k. 스킬 폴더에는 약 40개 파일(규칙 색인과 규칙 파일)이 있어 스킬 사용 실행마다 프로젝트로 복사되었습니다(실행당 평균 42.7개 새 파일).
- 스킬은 이름을 대지 않은 채 스킬 사용군 6/6 실행에서 읽혔습니다.
항목별 점수
| 항목 | 점수 | 이유 |
|---|---|---|
| 1_출력_품질 | 4.56 | 스킬 사용 시 평균 4.56/5(프로그램 검사, 작업별 표 참고). |
| 2_스킬_없음_대비_향상 | 3.77 | 스킬 없음 2.79 대비 +1.77점(작업당 n=2, 약 1점 미만은 노이즈). |
| 3_트리거 | 5.0 | 스킬 사용군 6/6 실행에서 스킬 파일을 읽었습니다. |
| 4_지침_이식성 | 3 | SKILL.md와 컴파일된 AGENTS.md, 약 40개 규칙 파일. 확인된 이득에 비해 규모가 큽니다. |
| 5_효율성 | 4 | 토큰 1.12배(실행당 110k vs 98k), 시간 0.97배(52초 vs 54초). |
| 6_안전성_및_위생 | 4 | 스캐너가 HIGH 3건을 표시했지만 모두 문서 텍스트에 있는 |
이 테스트의 한계
- 편집된 파일과 리뷰 텍스트에 대한 규칙 기반 검사를 했으며, 앱을 빌드하거나 실행한 적은 없습니다.
- 심어 둔 문제가 있는 단일 픽스처 화면이라, 같은 문제를 이름으로 언급하는 한 문장 프롬프트는 검사에 유난히 잘 맞는 상한선입니다.
- 셀당 n=2.
- 작업·군당 n=2: 약 1점 미만의 차이는 노이즈입니다.
- 규칙 기반 채점은 검사가 볼 수 있는 것만 측정하며, 취향이나 결과가 최선인지는 판단하지 못합니다.
보안
security.md를 참고하세요. 스캔: CRITICAL 0 / HIGH 3 / MEDIUM 0. 판정: 실행해도 안전(네트워크 차단 샌드박스). 깨끗한 스캔 결과가 스킬의 안전성을 증명하지는 않습니다.
결론
제스처를 추가할 때 에이전트를 Reanimated/Gesture Handler 스택으로 유도하는 데 유용하고 리뷰 탐지율도 높입니다. 그러나 기존 코드를 최적화할 때 에이전트가 전체 규칙 세트를 적용하게 만들지는 못했으며, 라이브러리 이름을 나열한 한 문장이 여기서는 더 나았습니다. RN 애니메이션 작업을 자주 추가한다면 설치하세요.
트랜스크립트
실행 로그: react-native-skills (Codex CLI, network off, per-run temp HOME/TMPDIR, one row per graded run.) 열: 작업, 그룹-회차, 점수(0-5), 토큰, 초, 통과한 검사, 에이전트가 연 스킬 파일. t1-review control-1: 점수 4.2, 토큰 86173, 초 48.3, 검사 2/2, 연 파일 없음 t1-review control-2: 점수 3.4, 토큰 85790, 초 52.6, 검사 2/2, 연 파일 없음 t1-review oneliner-1: 점수 5.0, 토큰 98552, 초 59.2, 검사 2/2, 연 파일 없음 t1-review oneliner-2: 점수 5.0, 토큰 85716, 초 49.5, 검사 2/2, 연 파일 없음 t1-review treatment-1: 점수 4.6, 토큰 72170, 초 47.4, 검사 2/2, 연 파일 react-native-skills t1-review treatment-2: 점수 4.6, 토큰 70886, 초 50.8, 검사 2/2, 연 파일 react-native-skills t2-optimize control-1: 점수 4.09, 토큰 105482, 초 60.5, 검사 5/7, 연 파일 없음 t2-optimize control-2: 점수 3.64, 토큰 105599, 초 61.9, 검사 4/7, 연 파일 없음 t2-optimize oneliner-1: 점수 5.0, 토큰 151869, 초 109.3, 검사 7/7, 연 파일 없음
18회 실행, 아티팩트 3개
샘플 출력
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.