React/TypeScript frontend development rules including type safety, component design, state management, and error handling. Use when implementing React components, TypeScript code, or frontend features.
64
—
Does it follow best practices?
Impact
—
No eval scenarios have been run
Passed
No known issues
Code first: names and types carry meaning; a comment must add what code cannot, and one comment per decision is enough. Frontend specifics:
Absolute Rule: Replace every any with unknown, generics, or union types. any disables type checking and causes runtime errors.
any Type Alternatives (Priority Order)
Type Guard Implementation Pattern
function isUser(value: unknown): value is User {
return typeof value === 'object' && value !== null && 'id' in value && 'name' in value
}Modern Type Features
const config = { apiUrl: '/api' } satisfies Config - Preserves inferenceconst ROUTES = { HOME: '/' } as const satisfies Routes - Immutable and type-safetype UserId = string & { __brand: 'UserId' } - Distinguish meaningtype EventName = \on${Capitalize}`` - Express string patterns with typesType Safety in Frontend Implementation
unknown, validate with type guardsunknown, validateunknown, validateType Safety in Data Flow
unknown) → Type Guard → State (Type Guaranteed)Type Complexity Management
Component Design Criteria
Server/Client Boundary (RSC frameworks only — e.g., Next.js App Router)
"use client" boundary at the smallest scope that needs itwindow, localStorage, event handlers) inside client components; calling them in a server component breaks the renderState Management Patterns
useState for component-specific stateData Flow Principles
// Immutable state update — always create new arrays/objects
setUsers(prev => [...prev, newUser])Function Design
function createUser({ name, email, role }: CreateUserParams) {}Props Design (Props-driven Approach)
Environment Variables
import.meta.env, Next.js/CRA via prefixed process.env. Raw, unprefixed access is undefined in the browser bundleundefined in the browser. The prefix differs per tool — match the project's bundler (Vite VITE_, Next.js public NEXT_PUBLIC_, CRA REACT_APP_)// Client-exposed env must carry the bundler's public prefix, or it is undefined in the browser.
// Vite: import.meta.env.VITE_API_URL
// Next.js: process.env.NEXT_PUBLIC_API_URL
const config = {
apiUrl: import.meta.env.VITE_API_URL || 'http://localhost:3000', // adjust accessor + prefix to the project's bundler
appName: import.meta.env.VITE_APP_NAME || 'My App'
}Security (Client-side Constraints)
.env files via .gitignore// Backend manages secrets, frontend accesses via proxy
const response = await fetch('/api/data') // Backend handles API key authenticationDependency Injection
Asynchronous Processing
async/awaittry-catch or Error BoundaryPromise<Result>)useEffect data fetches against out-of-order responses and post-unmount state updates — abort or ignore stale results (AbortController or a mounted flag), or use a server-state library (React Query/SWR) that cancels and dedupes. try-catch alone does not cover thisFormat Rules
PascalCase, variables/functions in camelCasesrc/)Clean Code Principles
console.log()Absolute Rule: Every caught error must be logged with context and either re-thrown to Error Boundary, returned as a Result error variant, or displayed as user-facing error state.
Fail-Fast Principle: Fail quickly on errors to prevent continued processing in invalid states
catch (error) {
logger.error('Processing failed', error)
throw error // Handle with Error Boundary or higher layer
}Result Type Pattern: Express errors with types for explicit handling
type Result<T, E> = { ok: true; value: T } | { ok: false; error: E }
// Example: Express error possibility with types
function parseUser(data: unknown): Result<User, ValidationError> {
if (!isValid(data)) return { ok: false, error: new ValidationError() }
return { ok: true, value: data as User }
}Custom Error Classes
export class AppError extends Error {
constructor(message: string, public readonly code: string, public readonly statusCode = 500) {
super(message)
this.name = this.constructor.name
}
}
// Purpose-specific: ValidationError(400), ApiError(502), NotFoundError(404)Layer-Specific Error Handling (React)
Structured Logging and Sensitive Information Protection Redact sensitive fields (password, token, apiKey, secret, creditCard) before logging
Asynchronous Error Handling in React
Basic Policy
Implementation Procedure: Understand Current State → Gradual Changes → Behavior Verification → Final Validation
Priority: Duplicate Code Removal > Large Function Division > Complex Conditional Branch Simplification > Type Safety Improvement
React.memo/useMemo/useCallback only as a profiler- or identity-justified escape hatch (a measured bottleneck, or stable reference identity for third-party APIs / effect dependencies)React.lazy and Suspense for code splitting66e3b29
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.