Summary
The react-dev plugin enforces opinionated React conventions: functional components only, TypeScript throughout, Vitest + Testing Library for tests, and Tailwind CSS for styling. It provides component/hook scaffolding that follows these patterns consistently. This is valuable because Claude Code generates inconsistent React code without explicit guidance — sometimes class components, sometimes inline styles, sometimes different test frameworks.
Original Intent
Plugin to guide React web development, preferred dependencies and conventions.
Commands
/react-dev:component
Purpose: Generate a new React component following project conventions.
Behavior:
- Ask user for:
- Component name (PascalCase)
- Component type: page, layout, UI component, form, modal/dialog
- Location hint (or auto-detect from existing component paths)
- Detect project conventions by scanning existing components:
- Directory structure:
components/<Name>/ (directory) vs components/<Name>.tsx (flat)
- Styling: Tailwind, CSS Modules, styled-components, or plain CSS
- State management: React context, Zustand, Jotai, Redux
- Export style: named vs default
- Determine target path:
- If
src/components/ exists → use it
- If
app/ (Next.js App Router) → use app/ for pages, components/ for UI
- If
pages/ (Next.js Pages Router) → use pages/ for pages, components/ for UI
- Generate component file:
// src/components/UserProfile/UserProfile.tsx
interface UserProfileProps {
userId: string;
onEdit?: () => void;
}
export function UserProfile({ userId, onEdit }: UserProfileProps) {
return (
<div className="...">
{/* component content */}
</div>
);
}
Conventions enforced:
- Always functional components (never class)
- Always TypeScript with explicit Props interface
- Always named export (not default, unless Next.js page)
- Props destructured in parameter
- No
React.FC — use plain function with typed props
- Generate associated files based on project patterns:
- Test file:
UserProfile.test.tsx with Testing Library
- Story file:
UserProfile.stories.tsx (if Storybook detected)
- Index file:
index.ts barrel export (if directory-based structure)
- Test file template:
import { render, screen } from "@testing-library/react";
import { describe, test, expect } from "vitest";
import { UserProfile } from "./UserProfile";
describe("UserProfile", () => {
test("renders without crashing", () => {
render(<UserProfile userId="123" />);
// Add assertions based on component content
});
});
- Output: list of created files
Edge cases:
- Component already exists → warn and offer to overwrite or pick new name
- No React detected in project → error with suggestion to install React first
- Next.js vs plain React vs Remix → adjust conventions accordingly
/react-dev:hook
Purpose: Generate a custom React hook following best practices.
Behavior:
- Ask user for:
- Hook name (must start with
use)
- Purpose description
- What it returns (data, loading state, error, functions)
- Detect where hooks live:
src/hooks/ (most common)
src/lib/hooks/ (Next.js convention)
- Colocated with feature (
src/features/<feature>/hooks/)
- Generate hook file:
// src/hooks/useDebounce.ts
import { useState, useEffect } from "react";
interface UseDebounceOptions {
delay?: number;
}
export function useDebounce<T>(value: T, options: UseDebounceOptions = {}) {
const { delay = 300 } = options;
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const timer = setTimeout(() => setDebouncedValue(value), delay);
return () => clearTimeout(timer);
}, [value, delay]);
return debouncedValue;
}
Conventions enforced:
- Name starts with
use
- Typed with generics where appropriate
- Options object pattern for configuration (not positional args)
- JSDoc with
@example usage
- Generate test file:
import { renderHook, act } from "@testing-library/react";
import { describe, test, expect, vi } from "vitest";
import { useDebounce } from "./useDebounce";
describe("useDebounce", () => {
test("returns initial value immediately", () => {
const { result } = renderHook(() => useDebounce("hello"));
expect(result.current).toBe("hello");
});
test("debounces value changes", async () => {
vi.useFakeTimers();
// ...
});
});
- Output: list of created files
Common hook patterns to suggest (based on purpose):
| Purpose |
Pattern |
Key imports |
| API data fetching |
useQuery wrapper |
useState, useEffect |
| Form state |
useForm |
useState, useCallback |
| Local storage |
useLocalStorage |
useState, useEffect |
| Media query |
useMediaQuery |
useState, useEffect |
| Intersection observer |
useInView |
useRef, useEffect |
| Keyboard shortcut |
useHotkey |
useEffect |
| Previous value |
usePrevious |
useRef, useEffect |
Edge cases:
- Hook name doesn't start with
use → auto-prefix and inform user
- Complex return type → suggest returning an object (not tuple) for readability
/react-dev:test
Purpose: Run React component tests and identify coverage gaps.
Behavior:
- Detect test framework:
vitest in devDependencies → bunx vitest run or npx vitest run
jest in devDependencies → bunx jest or npx jest
- Neither → suggest installing vitest
- Run tests:
bunx vitest run --reporter=verbose
- Analyze results:
- Show pass/fail summary
- For failures: show component name, test name, assertion error, file:line
- Run coverage:
bunx vitest run --coverage
- Identify untested components:
- Scan
src/components/**/*.tsx and src/hooks/**/*.ts
- Check for corresponding
*.test.tsx / *.test.ts
- List untested files:
Untested Components:
- src/components/Header/Header.tsx
- src/components/Sidebar/Sidebar.tsx
Untested Hooks:
- src/hooks/useAuth.ts
- Offer to generate test stubs for untested components
Testing best practices to include in command doc:
- Query by role, label, or text (not test-id) — accessible selectors
userEvent over fireEvent for realistic interactions
- Test behavior, not implementation details
- Don't test implementation details (internal state, hooks directly)
Edge cases:
- No tests exist → offer to scaffold test files for all components
- Jest + Enzyme → suggest migration to Vitest + Testing Library
- Tests reference DOM elements that don't exist → suggest checking component render
Hooks
None — this plugin operates through commands only.
File Manifest
| File |
Est. Lines |
Purpose |
commands/component.md |
100-120 |
Generate React component |
commands/hook.md |
90-110 |
Generate React hook |
commands/test.md |
80-100 |
Run tests and check coverage |
README.md |
170-210 |
Full plugin documentation |
.claude-plugin/plugin.json |
15-20 |
Plugin manifest |
README Outline
-
Overview — Opinionated React: functional, TypeScript, Vitest, Tailwind
-
Quick Start — Installation + generating first component
-
Commands — Table with all 3 commands
-
Conventions
| Aspect |
Convention |
Rationale |
| Components |
Functional only |
Hooks supersede class lifecycle |
| Language |
TypeScript |
Type safety, better DX |
| Styling |
Tailwind CSS |
Utility-first, no CSS file sprawl |
| Testing |
Vitest + Testing Library |
Fast, accessible queries |
| Exports |
Named (not default) |
Better refactoring, grep-able |
| Props |
Interface, not type |
Extensible, better error messages |
| State |
Zustand or Context |
Simple, no boilerplate |
-
Component Patterns — Page, Layout, UI, Form, Modal templates
-
Hook Patterns — Common custom hook patterns with examples
-
Testing Guide — Query priority, userEvent, what to test
-
Recommended Libraries
| Need |
Package |
Notes |
| Routing |
react-router / Next.js |
Framework-dependent |
| Forms |
react-hook-form |
Uncontrolled, performant |
| Validation |
zod |
Runtime + TypeScript inference |
| Data fetching |
@tanstack/react-query |
Caching, dedup, background refresh |
| Animation |
framer-motion |
Declarative, layout animations |
| Icons |
lucide-react |
Tree-shakeable, consistent |
| UI components |
shadcn/ui |
Copy-paste, not dependency |
Prerequisites
- React 18+ project with TypeScript
vitest + @testing-library/react (plugin will suggest installation if missing)
Quality Checklist
Summary
The
react-devplugin enforces opinionated React conventions: functional components only, TypeScript throughout, Vitest + Testing Library for tests, and Tailwind CSS for styling. It provides component/hook scaffolding that follows these patterns consistently. This is valuable because Claude Code generates inconsistent React code without explicit guidance — sometimes class components, sometimes inline styles, sometimes different test frameworks.Original Intent
Commands
/react-dev:componentPurpose: Generate a new React component following project conventions.
Behavior:
components/<Name>/(directory) vscomponents/<Name>.tsx(flat)src/components/exists → use itapp/(Next.js App Router) → useapp/for pages,components/for UIpages/(Next.js Pages Router) → usepages/for pages,components/for UIReact.FC— use plain function with typed propsUserProfile.test.tsxwith Testing LibraryUserProfile.stories.tsx(if Storybook detected)index.tsbarrel export (if directory-based structure)Edge cases:
/react-dev:hookPurpose: Generate a custom React hook following best practices.
Behavior:
use)src/hooks/(most common)src/lib/hooks/(Next.js convention)src/features/<feature>/hooks/)use@exampleusageCommon hook patterns to suggest (based on purpose):
useQuerywrapperuseState,useEffectuseFormuseState,useCallbackuseLocalStorageuseState,useEffectuseMediaQueryuseState,useEffectuseInViewuseRef,useEffectuseHotkeyuseEffectusePrevioususeRef,useEffectEdge cases:
use→ auto-prefix and inform user/react-dev:testPurpose: Run React component tests and identify coverage gaps.
Behavior:
vitestin devDependencies →bunx vitest runornpx vitest runjestin devDependencies →bunx jestornpx jestsrc/components/**/*.tsxandsrc/hooks/**/*.ts*.test.tsx/*.test.tsTesting best practices to include in command doc:
userEventoverfireEventfor realistic interactionsEdge cases:
Hooks
None — this plugin operates through commands only.
File Manifest
commands/component.mdcommands/hook.mdcommands/test.mdREADME.md.claude-plugin/plugin.jsonREADME Outline
Overview — Opinionated React: functional, TypeScript, Vitest, Tailwind
Quick Start — Installation + generating first component
Commands — Table with all 3 commands
Conventions
Component Patterns — Page, Layout, UI, Form, Modal templates
Hook Patterns — Common custom hook patterns with examples
Testing Guide — Query priority, userEvent, what to test
Recommended Libraries
react-router/ Next.jsreact-hook-formzod@tanstack/react-queryframer-motionlucide-reactshadcn/uiPrerequisites
vitest+@testing-library/react(plugin will suggest installation if missing)Quality Checklist