react-critic
harsh, evidence-backed code review for the JS ecosystem
A multi-critic review suite that catches what linters miss: stale closures, state ownership bugs, cache invalidation gaps,
unsafe RSC boundaries, missing rollback paths, and architecture risks.
Four specialized critics — each loaded with curated external skills from organizations like Vercel, Expo, Callstack, and Auth0 —
review React, Next.js, React Native/Expo code and pre-implementation plans through multiple perspectives (security, new-hire, ops)
and produce a structured verdict with evidence for every finding.
Overview
What It Does
Submit any React, Next.js, or React Native code — or a plan, RFC, or migration spec — and get a
structured, severity-rated review with concrete evidence for every finding.
The router detects what framework you're using and dispatches to the right specialist critic,
which loads curated skills from the teams that build the frameworks themselves.
Every review runs through multiple perspectives (security, new-hire, ops), a mandatory
self-audit that removes low-confidence claims, and a Realist Check that
calibrates severity against actual production risk — not theoretical worst cases.
Critic Architecture
js-critic-router
Dispatches to the correct critic
based on framework signals
react
react-critic
next
next-critic
rn/expo
react-native-critic
plan
proposal-critic
react-critic
Components, hooks, state management, rendering, performance
9 skills
next-critic
App Router, RSC, cache, revalidation, runtime, server actions
11 skills
react-native-critic
RN architecture, Expo, native UI, data fetching, CI/CD
18 skills
proposal-critic
Proposals, ADRs, RFCs, migration plans, architecture decisions
5 skills
Read-only critics. All four critics have disallowedTools: Write, Edit —
they can analyze code but never modify it. External skills inherit these restrictions.
How It Works
Review Process
Every review follows the same evidence-driven protocol, regardless of which critic handles it.
The router dispatches to the right critic, the critic loads up to 3 specialist skills, then runs a structured multi-phase analysis.
Phase 1
Route
js-critic-router reads
imports, file paths, config
→
Phase 2
Load Skills
1 core + 1 specialist
+ 1 shared (max 3)
→
Phase 3
Predict
3-5 pre-commitment
failure predictions
→
Phase 4
Analyze
Multi-perspective
review + gap analysis
→
Phase 5
Calibrate
Self-audit, Realist
Check, Security Gate
Perspectives (always on)
Security
New-hire
Ops
Perspectives (context-driven)
Perf Engineer
DX Maintainer
Product Reliability
Verdict Options
ACCEPT
ACCEPT w/ RESERVATIONS
REVISE
REJECT
Evidence-backed only. Every CRITICAL/MAJOR finding must cite file:line or quote the artifact directly.
Low-confidence claims are moved to Open Questions (unscored). Preference-only points are removed from scored sections.
Skills Catalog
45 locked identities across 16 trusted GitHub organizations, including 14 immutable deprecated tombstones. Each critic loads at most 3 active references per run:
1 core (always loaded), 1 specialist (context-matched), and 1 shared support skill.
react-critic 10 skills from 6 orgs
core
react-best-practices — React performance patterns, component design, rendering optimization (Vercel)
architecture
composition-patterns — Component API design, compound components, and provider boundaries (Vercel)
specialist
react-state-management — State ownership, local vs shared vs server state, mutation safety
specialist
react-modernization — Upgrade paths, migration patterns, deprecation handling
specialist
react-doctor — React application analysis, performance diagnosis, anti-pattern detection (Million.js)
specialist
typescript-react-reviewer — TypeScript + React patterns, type safety, API design
shared
javascript-testing-patterns — Test strategy, async testing, coverage patterns
shared
javascript-typescript-jest — Jest patterns for JS/TS projects (GitHub)
shared
modern-javascript-patterns — Modern JS idioms, ESM, async patterns
shared
api-security-best-practices — API trust boundaries, auth patterns, input validation
next-critic 12 skills from 7 orgs
core
react-best-practices — React and Next.js performance guidance (Vercel)
specialist
composition-patterns — Component API and server/client composition decisions (Vercel)
specialist
next-dev-loop — Executor-only runtime loop for Next 16.3+ with explicit environment gates (Vercel)
specialist
next-cache-components-optimizer — Executor-only Cache Components navigation optimization with explicit gates (Vercel)
specialist
nextjs-app-router-patterns — App Router architecture, layout nesting, parallel routes
specialist
nextjs-app-router-fundamentals — App Router fundamentals, server/client component split
auth
clerk-nextjs-patterns — Clerk auth integration for Next.js (Clerk)
auth
auth0 — Consolidated Auth0 guidance, selecting its Next.js section (Auth0)
auth
nextauth-authentication — NextAuth.js / Auth.js session and provider patterns
shared
javascript-testing-patterns — Test strategy, async testing, coverage patterns
shared
modern-javascript-patterns — Modern JS idioms, ESM, async patterns
shared
api-security-best-practices — API trust boundaries, auth patterns, input validation
react-native-critic 18 skills from 9 orgs
core
react-native-skills — React Native cross-platform patterns and performance (Vercel)
RN
react-native-best-practices — RN performance, native modules, bridge optimization (Callstack)
RN
upgrading-react-native — RN version upgrades, native dependency alignment (Callstack)
RN
upgrade-react-native — Community RN upgrade guide and migration patterns
RN
react-native-architecture — RN app architecture, module boundaries, state patterns
RN
react-native-design — RN UI/UX design patterns, cross-platform styling
RN
react-native-testing — React Native Testing Library patterns (Callstack)
Expo
expo-native-ui — Expo native UI components and platform APIs
Expo
expo-data-fetching — Expo data fetching, caching, offline patterns
Expo
expo-upgrade — Expo SDK version upgrades and migration
Expo
expo-router — Expo Router navigation and route structure; not an API-routes replacement
Expo
eas-workflows — Expo CI/CD, EAS Build/Submit, OTA updates
Expo
expo-dom — Expo DOM components and web-native bridging
platform
sentry-react-native-sdk — Sentry error monitoring integration for RN (Sentry)
platform
auth0 — Consolidated Auth0 guidance, selecting its React Native section (Auth0)
shared
javascript-testing-patterns — Test strategy, async testing, coverage patterns
shared
modern-javascript-patterns — Modern JS idioms, ESM, async patterns
shared
api-security-best-practices — API trust boundaries, auth patterns, input validation
proposal-critic 5 skills from 4 orgs
core
react-native-architecture — Architecture patterns for cross-framework proposal evaluation
specialist
typescript-react-reviewer — TypeScript + React API design review for proposals
shared
modern-javascript-patterns — Modern JS idioms for pattern evaluation
shared
api-security-best-practices — API trust boundaries for security review
shared
javascript-testing-patterns — Test strategy for plan feasibility checks
When Skills Activate
The router reads framework signals to pick a critic. The critic then selects skills based on what the code is doing.
Here are the jobs to be done that trigger each critic and its specialist skills.
react-critic activates when…
- Reviewing React components — hooks, JSX, component composition → loads react-best-practices
- State management changes — Redux, Zustand, Context, atoms → loads react-state-management
- Upgrading React versions — migration, deprecations, codemods → loads react-modernization
- Performance investigation — re-renders, memoization, virtualization → loads react-doctor
- TypeScript + API design — type safety, generics, interfaces → loads typescript-react-reviewer
next-critic activates when…
- App Router work —
app/ pages, layouts, loading states → loads react-best-practices plus an App Router specialist
- Cache Components optimization — loads next-cache-components-optimizer only when every Next 16.3+ runtime gate is verified
- Runtime iteration — loads next-dev-loop only with the required dev server, MCP endpoint, Turbopack, and browser tooling
- Auth integration — detects Clerk/Auth0/NextAuth imports → loads matching auth skill
- RSC boundary decisions —
'use client'/'use server' directives → loads app-router-patterns
react-native-critic activates when…
- RN component work —
View, FlatList, native modules → loads react-native-best-practices
- Expo app development —
expo imports, app.json, EAS → loads matching Expo skill
- RN version upgrade — native deps, metro config changes → loads upgrading-react-native
- Testing native code — RNTL patterns, mocking native modules → loads react-native-testing
- Observability / auth — Sentry or Auth0 imports detected → loads matching platform skill
proposal-critic activates when…
- RFC or ADR — "we propose", "alternatives considered" → runs full plan critique
- Migration plan — "rollback strategy", phased rollout → runs dependency audit + pre-mortem
- Architecture decision — system design, boundary definitions → runs devil's-advocate challenge
- Feature spec — design doc with pseudocode, no real code → runs feasibility + ambiguity scan
- Uses executor/stakeholder/skeptic perspectives instead of security/new-hire/ops
Routing signals. The js-critic-router (runs on Haiku for speed) reads imports, file paths, package.json deps, config files, and document keywords.
First match wins. Multi-framework monorepos get a MULTI verdict with a recommended review order.
External Skill Loading
Manifest-Based Loading
Each critic has a v2 external-skills-manifest.json listing the locked IDs it may load.
A central lock records explicit source paths, pinned commit SHAs, per-file hashes, and a deterministic bundle SHA-256.
At most 3 skills are loaded per review run, selected by priority and category relevance.
4 Manifests
.claude/skills/react-critic/references/
.claude/skills/next-critic/references/
.claude/skills/react-native-critic/references/
.claude/skills/proposal-critic/references/
id: vercel-labs/agent-skills/react-best-practices
repo_url: https://github.com/vercel-labs/agent-skills
source_path: skills/react-best-practices/SKILL.md
pinned_commit: 063bee94c3f4df8453406...
entry_sha256: per-file SHA-256
bundle_sha256: deterministic bundle SHA-256
lifecycle: active
Tier 1 Hardening Layers
Layer 1
Org Allowlist
TRUSTED_OWNERS in skill_security.py — 16 vetted GitHub organizations.
The verify script rejects any manifest entry from an unknown owner. New sources require explicit approval.
Layer 2
Content Hashing
Per-file size and SHA-256 plus a deterministic instruction-bundle digest are stored in the central v2 lock.
Runtime loading rechecks them before returning any external text.
Layer 3
Injection Scanning
10 regex patterns checked against every fetched text instruction/resource file: instruction overrides, identity hijacking,
script injection, base64 payloads, tool invocation injection, and more.
Layer 4
Scan Gate
If content scanning finds warnings, --approve is blocked.
An exception must name the exact skill ID and finding hash and is recorded in the lock. There is no global force switch.
Layer 5
Approval Gate
refresh_external_skills.py is dry-run by default and requires an explicit
--approve --ids ... or --approve --all transaction. No silent auto-updates.
Layer 6
Immutable Lineage
Renamed and retired identities remain as deprecated tombstones linked to active replacements.
Consumer manifests cannot enable deprecated entries.
Prompt Injection Scan Patterns
1 Instruction override — "ignore previous instructions"
2 Identity override — "you are now"
3 Behavioral override — "from now on...ignore"
4 System prompt reference — "system prompt/message"
5 Instruction disregard — "disregard all rules"
6 Script injection — <script> tags
7 JavaScript URI — javascript: protocol
8 Base64 data embed — data:*/;base64,
9 Tool invocation injection — <invoke>, <tool_use>
10 Priority override — "IMPORTANT: ignore/override"
Refresh Workflow
Step 1
Fetch HEAD
git ls-remote
for each repo
→
Step 2
Resolve Tree
Enumerate explicit
instruction bundle
→
Step 3
Hash Bundle
Per-file size/hash +
bundle SHA-256
→
Step 4
Scan Content
10 injection patterns
checked
→
Step 5
Write Lock
Only after explicit
transaction approval
dry-run Default
Shows diffs and hashes but writes nothing.
python3 scripts/refresh_external_skills.py
approve Write
Applies a focused pin + bundle update after review.
python3 scripts/refresh_external_skills.py --approve --ids ID
exception Exact finding
Records one reviewed ID + finding hash.
--allow-scan-warning ID:HASH
Scan gate. If content scanning finds warnings, --approve alone returns exit code 2 and writes nothing.
No lock or report is written. A human may approve only the exact skill ID and finding hash after reviewing the source context.
Verify Workflow
default Structure Validation
Runs in CI on every push. No network calls. Validates:
- Skill ID format:
owner/repo/name
- Valid 40-char commit SHA
- Valid source path, pin, per-file size/hash, and bundle digest
- Owner in
TRUSTED_OWNERS allowlist
- Valid active/deprecated lineage and consumer enablement
- No forbidden tracked files (no copied upstream content)
--verify-content Live Hash Check
Optional deep verification. Requires network. For each skill:
- Fetches every locked instruction/resource file at the pinned commit
- Checks size, per-file SHA-256, entry hash, and bundle digest
- Runs the injection scan again at runtime
- Fails on any mismatch or scan warning
- Fails closed if any hash, resource, lifecycle, or scan gate does not match
GitHub settings (manual). Upstream repos should enable signed commits, branch protection with PR reviews, and disable force push.
These are verified before adding a new owner to TRUSTED_OWNERS but cannot be enforced from this repo.