Skip to main content
ClaudeWave
Skill651 repo starsupdated today

typescript-rules

This Claude Code skill provides TypeScript and React development guidelines emphasizing type safety, code quality, and maintainability. Use it when building React components, writing TypeScript logic, managing application state, or handling external data to ensure proper type checking, prevent technical debt, and implement frontend features with robust error handling and clean code practices.

Install in Claude Code
Copy
git clone --depth 1 https://github.com/shinpr/claude-code-workflows /tmp/typescript-rules && cp -r /tmp/typescript-rules/dev-workflows-frontend/skills/typescript-rules ~/.claude/skills/typescript-rules
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

# TypeScript Development Rules (Frontend)

## Basic Principles

- **Aggressive Refactoring** - Prevent technical debt and maintain health
- **Delete code when no current caller exists** - YAGNI principle (Kent Beck)

## Comment Writing Rules
Code first: names and types carry meaning; a comment must add what code cannot, and one comment per decision is enough. Frontend specifics:
- **Comment intent, not markup**: explain why a component memoizes, guards, or re-renders — not what the JSX renders
- **Timeless content only**: Record decisions and rationale; leave chronological history to version control

## Type Safety

**Absolute Rule**: Replace every `any` with `unknown`, generics, or union types. `any` disables type checking and causes runtime errors.

**any Type Alternatives (Priority Order)**
1. **unknown Type + Type Guards**: Use for validating external input (API responses, localStorage, URL parameters)
2. **Generics**: When type flexibility is needed
3. **Union Types・Intersection Types**: Combinations of multiple types
4. **Type Assertions (Last Resort)**: Only when type is certain

**Type Guard Implementation Pattern**
```typescript
function isUser(value: unknown): value is User {
  return typeof value === 'object' && value !== null && 'id' in value && 'name' in value
}
```

**Modern Type Features**
- **satisfies Operator**: `const config = { apiUrl: '/api' } satisfies Config` - Preserves inference
- **const Assertion**: `const ROUTES = { HOME: '/' } as const satisfies Routes` - Immutable and type-safe
- **Branded Types**: `type UserId = string & { __brand: 'UserId' }` - Distinguish meaning
- **Template Literal Types**: `type EventName = \`on\${Capitalize<string>}\`` - Express string patterns with types

**Type Safety in Frontend Implementation**
- **React Props/State**: TypeScript manages types, unknown unnecessary
- **External API Responses**: Always receive as `unknown`, validate with type guards
- **localStorage/sessionStorage**: Treat as `unknown`, validate
- **URL Parameters**: Treat as `unknown`, validate
- **Form Input (Controlled Components)**: Type-safe with React synthetic events

**Type Safety in Data Flow**
- **Frontend → Backend**: Props/State (Type Guaranteed) → API Request (Serialization)
- **Backend → Frontend**: API Response (`unknown`) → Type Guard → State (Type Guaranteed)

**Type Complexity Management**
- **Props Design**:
  - Props count: 3-7 props ideal (consider component splitting if exceeds 10)
  - Optional Props: 50% or less (consider default values or Context if excessive)
  - Nesting: Up to 2 levels (flatten deeper structures)
- Type Assertions: Review design if used 3+ times
- **External API Types**: Relax constraints and define according to reality (convert appropriately internally)

## Coding Conventions

**Component Design Criteria**
- **Function components only**: Official React recommendation, optimizable by modern tooling (Exception: Error Boundary requires class component)
- **Custom Hooks**: Standard pattern for logic reuse and dependency injection
- **Component Hierarchy**: Use the project's adopted component architecture. When the project uses Atomic Design: Atoms → Molecules → Organisms → Templates → Pages. When the project uses Feature-based, Container-Presenter, or another structure: follow that structure consistently and document the chosen layering in the project README or design doc
- **Co-location**: Place tests, styles, and related files alongside components

**Server/Client Boundary (RSC frameworks only — e.g., Next.js App Router)**
- Default to server components for data fetching and rendering; isolate interactivity behind a `"use client"` boundary at the smallest scope that needs it
- Keep browser-only APIs (`window`, `localStorage`, event handlers) inside client components; calling them in a server component breaks the render
- N/A for client-only SPAs (e.g., Vite) — skip when the project has no server-component runtime

**State Management Patterns**
- **Local State**: `useState` for component-specific state
- **Context API**: For sharing state across component tree (theme, auth, etc.)
- **Custom Hooks**: Encapsulate state logic and side effects
- **Server State**: React Query or SWR for API data caching

**Data Flow Principles**
- **Single Source of Truth**: Each piece of state has one authoritative source
- **Unidirectional Flow**: Data flows top-down via props
- **Immutable Updates**: Use immutable patterns for state updates

```typescript
// Immutable state update — always create new arrays/objects
setUsers(prev => [...prev, newUser])
```

**Function Design**
- **0-2 parameters maximum**: Use object for 3+ parameters
  ```typescript
  function createUser({ name, email, role }: CreateUserParams) {}
  ```

**Props Design (Props-driven Approach)**
- Props are the interface: Define all necessary information as props
- Pass all data dependencies as props; use Context only for cross-cutting concerns (theme, auth, locale)
- Type-safe: Always define Props type explicitly

**Environment Variables**
- **Use the build tool's env accessor**: read client-side env through the bundler's exposed accessor — Vite via `import.meta.env`, Next.js/CRA via prefixed `process.env`. Raw, unprefixed access is `undefined` in the browser bundle
- **Only prefixed vars reach the client**: build tools expose only vars carrying their public prefix; an unprefixed var is `undefined` in the browser. The prefix differs per tool — match the project's bundler (Vite `VITE_`, Next.js public `NEXT_PUBLIC_`, CRA `REACT_APP_`)
- Centrally manage env through a typed config object with a default for every variable

```typescript
// 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.VIT
acceptance-test-generatorSubagent

Generates integration/E2E test skeletons from Design Doc ACs using ROI-based selection and journey-based E2E reservation. Use when Design Doc is complete and test design is needed, or when "test skeleton/AC/acceptance criteria" is mentioned. Behavior-first approach for minimal tests with maximum coverage.

code-reviewerSubagent

Validates Design Doc compliance and implementation completeness from third-party perspective. Use PROACTIVELY after implementation completes or when "review/implementation check/compliance" is mentioned. Provides acceptance criteria validation and quality reports.

code-verifierSubagent

Validates consistency between PRD/Design Doc and code implementation. Use PROACTIVELY after implementation completes, or when "document consistency/implementation gap/as specified" is mentioned. Uses multi-source evidence matching to identify discrepancies.

codebase-analyzerSubagent

Analyzes existing codebase objectively for facts about implementation, user behavior patterns, and technical architecture. Use when existing code needs to be understood without hypothesis bias. Invoked before Design Doc creation to produce focused guidance for technical designers.

design-syncSubagent

Detects conflicts across multiple Design Docs and provides structured reports. Use when multiple Design Docs exist, or when "consistency/conflict/sync/between documents" is mentioned. Focuses on detection and reporting only, no modifications.

document-reviewerSubagent

Reviews document consistency and completeness, providing approval decisions. Use PROACTIVELY after PRD/UI Spec/Design Doc/work plan creation, or when "document review/approval/check" is mentioned. Detects contradictions and rule violations with improvement suggestions.

integration-test-reviewerSubagent

Verifies consistency between test skeleton comments and implementation code. Use PROACTIVELY after test implementation completes, or when "test review/skeleton verification" is mentioned. Returns quality reports with failing items and fix instructions.

investigatorSubagent

Comprehensively collects problem-related information and creates evidence matrix. Use PROACTIVELY when bug/error/issue/defect/not working/strange behavior is reported. Reports only observations without proposing solutions.