Install
$ agentstack add skill-leejpsd-typescript-react-patterns-typescript-react-patterns ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
TypeScript for React & Next.js — Agent Skill
A structured reference for AI coding agents assisting frontend engineers with TypeScript, React, and Next.js in production environments.
Agent Behavior Rules
Before answering, always verify:
- Server or client? Server Components, Server Actions, and Route Handlers have different type constraints than
"use client"components. - Runtime validation needed? Static types do NOT validate API responses, URL params, form data, or localStorage. Data crossing a trust boundary requires Zod or equivalent.
- App Router or Pages Router? Patterns differ significantly. If unclear, ask.
- TypeScript version?
satisfiesrequires 5.0+. Check before suggesting version-dependent features. - Next.js version?
paramsis aPromisein 15+. Caching model changed in 16+.
Assumptions the agent must NOT make:
- That API responses match their TypeScript types at runtime
- That
searchParamsvalues are the expected type (they are alwaysstring | string[] | undefined) - That
anyin existing code is intentional - That a type assertion (
as) is justified without checking context - That server-only imports are safe in client components
- That
useEffectdependencies in existing code are correct
When uncertain:
- State tradeoffs explicitly rather than picking one approach silently
- Mark unstable or version-dependent patterns as such
- Distinguish: [HARD RULE] (violating causes bugs) / [DEFAULT] (override with reason) / [SITUATIONAL] (depends on context)
Decision Guide
Quick: What pattern should I use?
| Situation | Start here | |-----------|-----------| | Typing component Props, children, events, refs | → react-typescript-patterns.md | | Narrowing unions, unknown, type guards, utility types | → typescript-core.md | | Next.js params, searchParams, Server Actions, RSC boundary | → nextjs-typescript.md | | Discriminated unions, conditional props, compound components | → component-patterns.md | | API responses, fetch typing, TanStack Query, caching | → data-fetching-and-api-types.md | | Form state, validation, controlled vs uncontrolled | → forms-and-validation.md | | Local state vs context vs server state vs Zustand | → state-management.md | | Re-renders, memoization, accessibility | → performance-and-accessibility.md | | Type errors, hydration, stale state, effect bugs | → debugging-checklists.md (hub) + playbooks/ | | PR review, risk vs preference, architecture smells | → code-review-rules.md | | Common mistakes, cargo-cult patterns | → anti-patterns.md |
Flowchart: Is this data safe to use?
Data comes from...
├─ Inside the app (useState, useReducer, computed)
│ → Static typing is sufficient. No runtime validation needed.
│
├─ Outside the app (API, URL, FormData, localStorage, postMessage)
│ → [HARD RULE] Validate at runtime. Use Zod or equivalent.
│ │
│ ├─ API response → schema.parse(await res.json())
│ ├─ URL params → schema.parse(searchParams)
│ ├─ FormData → schema.safeParse({ field: formData.get('field') })
│ ├─ localStorage → schema.safeParse(JSON.parse(stored))
│ └─ postMessage → schema.safeParse(event.data)
│
└─ Third-party library callback
→ Check library types. Add runtime guard if types seem wrong.
Flowchart: Where should this state live?
Is this data from a server/API?
├─ Yes → TanStack Query (NOT useState). See data-fetching-and-api-types.md
│
└─ No → Is it shareable via URL? (filters, page, sort)
├─ Yes → searchParams or nuqs. See state-management.md
│
└─ No → How many components need it?
├─ 1 component → useState or useReducer
├─ 2-3 in same tree → Lift state up (props)
└─ Many across trees → How often does it change?
├─ Rarely (theme, locale, auth) → Context
└─ Often (cart, notifications) → Zustand with selectors
Flowchart: Should I memoize this?
Is there a measured performance problem?
├─ No → Don't memoize. Stop here.
│
└─ Yes → Can you restructure instead?
├─ Yes → Move state down, extract components. See performance-and-accessibility.md
│
└─ No → What needs memoizing?
├─ Expensive computation → useMemo (verify it's truly expensive)
├─ Callback to memoized child → useCallback
└─ Component in a long list → React.memo (verify props are stable)
Quick: hard rule vs default vs situational
| Label | Meaning | Example | |-------|---------|---------| | [HARD RULE] | Violating causes bugs or security issues. No exceptions. | "Validate API responses at runtime" | | [DEFAULT] | Recommended unless you have a documented reason to deviate. | "Use interface for Props" | | [SITUATIONAL] | Depends on context. Both options are valid. Explain your choice. | "Polymorphic components — only for design-system foundations" |
Code Generation Checklist
Before generating TypeScript/React/Next.js code:
Context
- [ ] Confirmed: server or client code?
- [ ] Confirmed: App Router or Pages Router?
- [ ] Confirmed: TypeScript strict mode enabled?
Type Safety
- [ ] No
any— useunknownwith validation or proper types - [ ] No
aswithout documented justification - [ ] External data (API, URL, form, storage) validated at runtime
- [ ] Props use
interface, only truly optional fields have?
React
- [ ]
childrentyped asReact.ReactNode - [ ] Event handler Props expose values, not event objects
- [ ] Effects have stable dependencies and cleanup functions
- [ ]
"use client"only where needed, as deep as possible - [ ] No server data duplicated into
useState
Next.js (15+)
- [ ]
paramsandsearchParamsawaited - [ ] Server Actions validate FormData with Zod
- [ ] Sensitive code protected with
import 'server-only' - [ ] Cross-boundary Props are JSON-serializable (no functions, Dates, Maps)
Accessibility
- [ ] Form inputs have associated labels
- [ ] Error messages use
role="alert" - [ ] Interactive elements are keyboard-accessible
Code Review Checklist
Flag as risk (likely bug or maintenance problem)
anywithout documented reasonason external data without validation!non-null assertion without prior guarduseEffectwith object/array dependencies (likely unstable)- Missing
useEffectcleanup - Server data copied into
useState "use client"at page/layout level- Functions passed across server/client boundary
params/searchParamsnot awaited (Next.js 15+)- Server Action without FormData validation
Flag as preference (mention, don't block)
typevsinterfacefor object shapes- Handler naming convention
- File/folder organization style
- Import ordering
File Index
| File | Scope | |------|-------| | typescript-core.md | Narrowing, unions, generics, utility types, inference, unknown vs any, as const, satisfies | | react-typescript-patterns.md | Props, children, events, hooks, context, forwardRef | | nextjs-typescript.md | App Router types, params, searchParams, Server Actions, RSC boundaries, metadata | | component-patterns.md | Discriminated union Props, compound components, controlled/uncontrolled, polymorphic | | data-fetching-and-api-types.md | Fetch typing, Zod validation, TanStack Query, safe response handling | | forms-and-validation.md | Form state, Zod, react-hook-form, Server Actions, progressive enhancement | | state-management.md | Local state, Context, Zustand, TanStack Query, URL state, decision matrix | | performance-and-accessibility.md | Memoization tradeoffs, effect stability, semantic HTML, ARIA patterns | | debugging-checklists.md | Quick diagnosis router, serialization issues, null access, re-render errors | | code-review-rules.md | Risk vs preference, architecture smells, review comment templates | | anti-patterns.md | 12 common mistakes with root causes and fixes |
playbooks/ — Step-by-step debugging guides (consult when diagnosing specific bugs)
| File | Scope | |------|-------| | type-error-debugging.md | Systematic type error resolution with React/Next.js-specific errors | | hydration-issues.md | SSR/CSR mismatch diagnosis flowchart and fix patterns | | effect-dependency-bugs.md | Infinite loops, stale closures, missing cleanups, real-world debounce example |
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: leejpsd
- Source: leejpsd/typescript-react-patterns
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.