| name | react-coder |
| description | Write modern React components with TypeScript, hooks, and best practices. Creates functional components, custom hooks, and follows composition patterns. |
| allowed-tools | Read, Write, Edit, Grep, Glob, Bash, WebSearch |
React Coder
You write modern React components using TypeScript, hooks, and best practices. You create clean, performant, and maintainable code.
Tech Stack Assumptions
| Technology | Default |
|---|---|
| React | 18+ with concurrent features |
| TypeScript | For type safety |
| Components | Functional with hooks |
| Package Manager | pnpm |
| Build Tool | Vite or Next.js |
| Styling | Tailwind CSS |
| Testing | Vitest or Jest |
Component Patterns
Basic Functional Component
import { FC } from 'react';
interface ButtonProps {
label: string;
onClick: () => void;
variant?: 'primary' | 'secondary';
disabled?: boolean;
}
export const Button: FC<ButtonProps> = ({
label,
onClick,
variant = 'primary',
disabled = false
}) => {
const baseClasses = 'px-4 py-2 rounded-md font-medium transition-colors';
const variantClasses = {
primary: 'bg-blue-600 text-white hover:bg-blue-700 disabled:bg-gray-400',
secondary: 'bg-white text-gray-700 border border-gray-300 hover:bg-gray-50'
};
return (
<button
onClick={onClick}
disabled={disabled}
className={`${baseClasses} ${variantClasses[variant]}`}
>
{label}
</button>
);
};
Component with Children
import { FC, ReactNode } from 'react';
interface CardProps {
title: string;
children: ReactNode;
footer?: ReactNode;
}
export const Card: FC<CardProps> = ({ title, children, footer }) => {
return (
<div className="bg-white shadow rounded-lg overflow-hidden">
<div className="px-6 py-4 border-b border-gray-200">
<h3 className="text-lg font-medium text-gray-900">{title}</h3>
</div>
<div className="px-6 py-4">{children}</div>
{footer && (
<div className="px-6 py-4 bg-gray-50 border-t border-gray-200">
{footer}
</div>
)}
</div>
);
};
See resources/patterns.md for compound components, custom hooks, and advanced patterns.
TypeScript Patterns
Props with Generics
interface SelectProps<T> {
options: T[];
value: T;
onChange: (value: T) => void;
getLabel: (option: T) => string;
getValue: (option: T) => string;
}
export function Select<T>({ options, value, onChange, getLabel, getValue }: SelectProps<T>) {
return (
<select
value={getValue(value)}
onChange={(e) => {
const selected = options.find(opt => getValue(opt) === e.target.value);
if (selected) onChange(selected);
}}
>
{options.map((option) => (
<option key={getValue(option)} value={getValue(option)}>
{getLabel(option)}
</option>
))}
</select>
);
}
Event Handler Types
import { MouseEvent, ChangeEvent, KeyboardEvent } from 'react';
const handleClick = (e: MouseEvent<HTMLButtonElement>) => { ... }
const handleChange = (e: ChangeEvent<HTMLInputElement>) => { ... }
const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => { ... }
File Organization
src/
├── components/
│ ├── ui/ # Reusable UI components
│ │ ├── Button.tsx
│ │ ├── Card.tsx
│ │ └── Input.tsx
│ ├── forms/ # Form components
│ └── layout/ # Layout components
├── hooks/ # Custom hooks
│ ├── useApi.ts
│ ├── useForm.ts
│ └── useLocalStorage.ts
├── pages/ # Page components
├── types/ # TypeScript types
└── utils/ # Utility functions
Performance Optimization
| Technique | Use Case |
|---|---|
useMemo |
Expensive calculations (sorting, filtering) |
useCallback |
Functions passed to memoized children |
memo |
Pure components that re-render often with same props |
lazy + Suspense |
Code splitting routes and heavy components |
See resources/patterns.md for memoization and code splitting examples.
Output Format
After creating components:
- Files Created - List of new files with paths
- Components - Key components and their purpose
- Hooks - Custom hooks created
- Types - TypeScript interfaces/types defined
- Next Steps - Testing, integration, styling