From coding-standards
Review TypeScript and Next.js code against team conventions — type safety, component patterns, API routes, testing, and bundle hygiene. Auto-invoked when reviewing .ts/.tsx files.
npx claudepluginhub hpsgd/turtlestack --plugin coding-standardsThis skill is limited to using the following tools:
Review TypeScript and Next.js code against team standards. This is the complete TypeScript review methodology — every check has a specific grep or read pattern, and every finding requires evidence.
Compares coding agents like Claude Code and Aider on custom YAML-defined codebase tasks using git worktrees, measuring pass rate, cost, time, and consistency.
Designs and optimizes AI agent action spaces, tool definitions, observation formats, error recovery, and context for higher task completion rates.
Designs, implements, and audits WCAG 2.2 AA accessible UIs for Web (ARIA/HTML5), iOS (SwiftUI traits), and Android (Compose semantics). Audits code for compliance gaps.
Review TypeScript and Next.js code against team standards. This is the complete TypeScript review methodology — every check has a specific grep or read pattern, and every finding requires evidence.
Execute all six passes. Do not skip. Mark each pass complete as you finish it.
The type system exists to catch bugs at compile time. Every any defeats that purpose.
any usage — grep for : any, as any, <any>, any[], any), Record<string, any>:
grep -rn '\bany\b' --include='*.ts' --include='*.tsx' [changed files]
Every hit is a finding unless it meets one of these exceptions:
unknown genuinely breaks the contract (rare — explain why)anyThe fix is always one of: use unknown and narrow, define a specific type, or use a generic parameter.
Missing explicit return types on exports — every exported function and method must have an explicit return type. This prevents accidental API changes.
grep -rn 'export.*function\|export.*=.*=>' --include='*.ts' --include='*.tsx' [changed files]
Then read each match and verify the return type is specified. Arrow functions assigned to exported const also need return types.
Type assertions (as) — grep for as [A-Z] in changed files. Each assertion is a potential lie to the compiler:
as unknown as X — almost always wrong. Find the real type.as X where a type guard or narrowing would work — prefer narrowing.as const — acceptable, not a finding.Non-null assertions (!) — grep for patterns like variable!., array![0], result!:
grep -rn '[a-zA-Z]!\.' --include='*.ts' --include='*.tsx' [changed files]
Each is a finding. Replace with proper null checks, optional chaining, or early returns.
Strict mode compliance — verify tsconfig.json has "strict": true. If the project does not use strict mode, flag it as a critical finding.
Import order — imports must follow this grouping (separated by blank lines):
react, next, lodash)@org/shared, @/lib)./, ../)Type-only imports — when importing something used only as a type, use the inline type keyword:
// correct
import { useState, type FC } from 'react';
import { type User } from '@/types';
// wrong — imports the value at runtime unnecessarily
import { FC } from 'react';
Grep for imported names and check if they appear only in type positions (: Type, <Type>, as Type, extends Type).
Barrel exports — component directories should use index.ts barrel files. But barrel files must not re-export everything from deep paths. Each barrel should export only the public API of that directory.
No CommonJS — grep for require(, module.exports, exports.:
grep -rn 'require(\|module\.exports\|exports\.' --include='*.ts' --include='*.tsx' [changed files]
Every hit is a finding. Use ESM import/export exclusively.
Circular imports — if you suspect a circular dependency (runtime errors, undefined values), trace the import chain. Two files importing from each other is always a finding.
Files:
PascalCase.tsx (e.g., UserProfile.tsx)kebab-case.ts (e.g., api-client.ts)_hero-section.tsx, _utils.ts)[name].test.ts or [name].spec.ts, colocated with sourceExports:
PascalCase (UserProfile, ApiResponse)camelCase (getUserById, formatDate)UPPER_SNAKE_CASE for true constants, camelCase for configuration objectsPascalCase name, PascalCase membersis/has/should/can prefix (isLoading, hasError)Interfaces vs types:
interface for object shapes that could be extended (props, API contracts)type for unions, intersections, mapped types, utility typesinterface for unions. Never use type for a plain object shape that represents a contract.Skip this pass if the project does not use Next.js.
Server vs Client Components:
'use client' only when they use hooks, event handlers, browser APIs, or state.'use client' and verify each file actually needs it. A file that imports useState or useEffect needs it. A file that only renders props does not.No client-side data operations:
.filter(, .sort(, .slice( on data arrays in Client Components. Each hit on a dataset (not a small static array) is a finding.Server Actions — prefer server actions over API routes for mutations. Server actions colocate the mutation with the form.
Image optimization — use next/image, not raw <img> tags.
Metadata — pages should export metadata or generateMetadata, not set <title> manually.
Skip if the project does not use Tailwind.
[ in className strings: text-[14px], w-[327px], bg-[#ff0000]. Each is a finding unless no standard Tailwind class exists for that value.style= attributes alongside Tailwind classes. Pick one approach.sm:, md:, lg: breakpoints. If a component has no responsive modifiers and renders content, verify it works on mobile.dark: variants.| Pattern | Why it's wrong | Fix |
|---|---|---|
as any | Defeats type checking | Use unknown + narrowing |
// @ts-ignore | Hides real errors | Fix the type error or use @ts-expect-error with explanation |
useEffect for derived state | Causes extra renders | Compute during render |
key={index} on dynamic lists | Breaks reconciliation | Use stable unique ID |
export default | Makes refactoring harder | Use named exports |
enum for simple unions | Generates runtime code | Use as const union |
satisfies operator for type-safe object literals### [SEVERITY] [Pass]: [Short description]
**File:** `path/to/file.tsx:42`
**Evidence:** [grep output or code showing the violation]
**Standard:** [which rule is violated]
**Fix:** [concrete code change]
## TypeScript Review
### Summary
- Files reviewed: N
- Type safety: X findings (Y `any`, Z missing return types)
- Import hygiene: X findings
- Naming: X findings
- Next.js patterns: X findings (or N/A)
- Styling: X findings (or N/A)
- Tests: X findings
### Findings
[grouped by severity: critical, important, suggestion]
### Clean Areas
[what was done well]
If everything passes, say so: "No findings. TypeScript review complete — all changed files comply with team standards." Do not invent issues.
/coding-standards:review-standards — cross-cutting quality and writing style checks that apply to all languages. Run alongside this review./coding-standards:review-git — commit message and PR conventions. Run when reviewing a PR.