javascript-react
SKILL.md
Expert JavaScript & React Development
Write modern, performant, type-safe JavaScript and React code following current best practices.
Core Principles
- Prefer composition over inheritance - Use hooks, HOCs, and render props strategically
- Minimize re-renders - Memoize appropriately, lift state only when necessary
- Type everything - Use TypeScript for any non-trivial code
- Fail fast - Validate inputs, use error boundaries, handle edge cases
JavaScript Patterns
Modern Syntax Defaults
// Prefer const, use let only when reassignment needed
const config = { timeout: 5000 };
let count = 0;
// Destructuring with defaults
const { name, age = 18, ...rest } = user;
const [first, second, ...remaining] = items;
// Optional chaining and nullish coalescing
const value = obj?.deeply?.nested?.value ?? 'default';
// Template literals for complex strings
const query = `SELECT * FROM ${table} WHERE id = ${id}`;
Async Patterns
// Prefer async/await over raw promises
async function fetchData(url) {
try {
const response = await fetch(url);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return await response.json();
} catch (error) {
console.error('Fetch failed:', error);
throw error;
}
}
// Parallel execution
const [users, posts] = await Promise.all([fetchUsers(), fetchPosts()]);
// Sequential with error handling
const results = await Promise.allSettled([task1(), task2(), task3()]);
const successes = results.filter(r => r.status === 'fulfilled').map(r => r.value);
Advanced patterns reference
See references/modern-javascript.md for:
- Closures and module patterns
- Proxy and Reflect
- Generators and async iterators
- WeakMap/WeakSet for memory management
- Custom iterables
React Patterns
Component Structure
// Functional components with TypeScript
interface ButtonProps {
variant?: 'primary' | 'secondary' | 'danger';
size?: 'sm' | 'md' | 'lg';
disabled?: boolean;
onClick?: () => void;
children: React.ReactNode;
}
export function Button({
variant = 'primary',
size = 'md',
disabled = false,
onClick,
children,
}: ButtonProps) {
return (
<button
className={cn(styles.button, styles[variant], styles[size])}
disabled={disabled}
onClick={onClick}
>
{children}
</button>
);
}
Hooks Best Practices
// Custom hooks extract reusable logic
function useDebounce<T>(value: T, delay: number): T {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const timer = setTimeout(() => setDebouncedValue(value), delay);
return () => clearTimeout(timer);
}, [value, delay]);
return debouncedValue;
}
// useMemo for expensive computations
const sortedItems = useMemo(
() => items.slice().sort((a, b) => a.name.localeCompare(b.name)),
[items]
);
// useCallback for stable function references
const handleSubmit = useCallback(
async (data: FormData) => {
await submitForm(data);
onSuccess();
},
[onSuccess]
);
State Management Decision Tree
- Local UI state →
useState - Complex local state with actions →
useReducer - Shared state within subtree → Context +
useReducer - Global app state → Zustand, Jotai, or Redux Toolkit
- Server state (fetching/caching) → TanStack Query or SWR
Advanced React patterns reference
See references/react-patterns.md for:
- Compound components
- Render props and HOCs
- Controlled vs uncontrolled patterns
- Error boundaries
- Suspense and lazy loading
- Server components (React 19+)
TypeScript Patterns
Type Utilities
// Discriminated unions for exhaustive checking
type Result<T> = { ok: true; value: T } | { ok: false; error: Error };
// Generic constraints
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
// Conditional types
type Awaited<T> = T extends Promise<infer U> ? U : T;
// Template literal types
type EventName = `on${Capitalize<string>}`;
Strict Configuration
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"noImplicitReturns": true,
"exactOptionalPropertyTypes": true
}
}
Performance Optimization
See references/performance.md for comprehensive optimization strategies.
Quick Reference
| Problem | Solution |
|---|---|
| Unnecessary re-renders | React.memo, useMemo, useCallback |
| Large bundle size | Code splitting, React.lazy, tree shaking |
| Slow lists | Virtualization (@tanstack/react-virtual) |
| Layout thrashing | useLayoutEffect, batch DOM reads |
| Memory leaks | Cleanup in useEffect, AbortController |
Critical Anti-patterns
// ❌ Creating objects/arrays in render
<Component style={{ color: 'red' }} items={[1, 2, 3]} />
// ✅ Stable references
const style = useMemo(() => ({ color: 'red' }), []);
const items = useMemo(() => [1, 2, 3], []);
// ❌ Index as key with dynamic lists
{items.map((item, i) => <Item key={i} {...item} />)}
// ✅ Stable unique keys
{items.map(item => <Item key={item.id} {...item} />)}
Testing
See references/testing.md for testing strategies.
Testing Stack
- Unit tests: Vitest (fast, ESM-native)
- Component tests: React Testing Library
- E2E tests: Playwright
- Type tests:
tsdorexpect-type
Testing Principles
- Test behavior, not implementation
- Prefer integration tests over unit tests
- Mock at network boundary (MSW), not internal modules
- Use realistic data with factories
Project Structure
src/
├── components/ # Reusable UI components
│ └── Button/
│ ├── Button.tsx
│ ├── Button.test.tsx
│ └── index.ts
├── features/ # Feature-specific code
│ └── auth/
│ ├── components/
│ ├── hooks/
│ ├── api.ts
│ └── types.ts
├── hooks/ # Shared custom hooks
├── lib/ # Utilities and helpers
├── types/ # Shared TypeScript types
└── App.tsx
Tooling Recommendations
| Category | Tool | Notes |
|---|---|---|
| Build | Vite | Fast dev, good defaults |
| Linting | ESLint + typescript-eslint | Use flat config |
| Formatting | Prettier | Or Biome for speed |
| Package manager | pnpm | Fast, disk efficient |
| Runtime validation | Zod | Infer TS types from schemas |
Weekly Installs
4
Repository
jaredlander/freshbooks-speedFirst Seen
2 days ago
Installed on
claude-code3
windsurf2
trae2
opencode2
codex2
antigravity2