@codihaus/claude-skills 1.6.16 → 1.6.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -14,9 +14,10 @@ When skills detect a tech stack (via `stack.md`), they load the relevant stack f
|
|
|
14
14
|
|
|
15
15
|
| Stack | Folder | Type | Status |
|
|
16
16
|
|-------|--------|------|--------|
|
|
17
|
-
|
|
|
18
|
-
| Nuxt.js | `nuxt/` | Vue + SSR Framework | Ready |
|
|
17
|
+
| React | `react/` | UI Library | Ready |
|
|
19
18
|
| Next.js | `nextjs/` | React + SSR Framework | Ready |
|
|
19
|
+
| Nuxt.js | `nuxt/` | Vue + SSR Framework | Ready |
|
|
20
|
+
| Directus | `directus/` | Backend BaaS | Ready |
|
|
20
21
|
| Prisma | `prisma/` | ORM | Planned |
|
|
21
22
|
| Supabase | `supabase/` | Backend BaaS | Planned |
|
|
22
23
|
|
|
@@ -0,0 +1,579 @@
|
|
|
1
|
+
# React
|
|
2
|
+
|
|
3
|
+
> JavaScript library for building user interfaces with components
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
**What it is:**
|
|
8
|
+
- Component-based UI library (not a full framework)
|
|
9
|
+
- Virtual DOM for efficient updates
|
|
10
|
+
- Declarative and composable
|
|
11
|
+
- Unidirectional data flow
|
|
12
|
+
- Hooks for state and side effects
|
|
13
|
+
- React 18+ with Concurrent features
|
|
14
|
+
|
|
15
|
+
**When to use:**
|
|
16
|
+
- Building interactive user interfaces
|
|
17
|
+
- Single-page applications (SPAs)
|
|
18
|
+
- Component-based architecture
|
|
19
|
+
- Projects needing UI flexibility
|
|
20
|
+
- Teams familiar with JavaScript/JSX
|
|
21
|
+
|
|
22
|
+
**Key concepts:**
|
|
23
|
+
- **Components** = Building blocks (functions returning JSX)
|
|
24
|
+
- **Props** = Data passed down from parent
|
|
25
|
+
- **State** = Component-local data
|
|
26
|
+
- **Hooks** = Functions for state/effects (useState, useEffect, etc.)
|
|
27
|
+
- **JSX** = JavaScript XML syntax
|
|
28
|
+
- **Virtual DOM** = In-memory representation for efficient updates
|
|
29
|
+
- **Reconciliation** = Diffing algorithm for minimal DOM updates
|
|
30
|
+
|
|
31
|
+
## Best Practices
|
|
32
|
+
|
|
33
|
+
### Project Structure
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
react-app/
|
|
37
|
+
├── src/
|
|
38
|
+
│ ├── components/ # Reusable components
|
|
39
|
+
│ │ ├── ui/ # UI primitives (Button, Input)
|
|
40
|
+
│ │ ├── forms/ # Form components
|
|
41
|
+
│ │ └── common/ # Shared components (Header, Footer)
|
|
42
|
+
│ ├── features/ # Feature-based modules
|
|
43
|
+
│ │ └── auth/
|
|
44
|
+
│ │ ├── components/ # Feature-specific components
|
|
45
|
+
│ │ ├── hooks/ # Feature-specific hooks
|
|
46
|
+
│ │ └── utils/ # Feature utilities
|
|
47
|
+
│ ├── hooks/ # Global custom hooks
|
|
48
|
+
│ ├── context/ # Context providers
|
|
49
|
+
│ ├── utils/ # Helper functions
|
|
50
|
+
│ ├── types/ # TypeScript types
|
|
51
|
+
│ ├── constants/ # Constants and configs
|
|
52
|
+
│ └── App.tsx # Root component
|
|
53
|
+
└── public/ # Static assets
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Component Patterns
|
|
57
|
+
|
|
58
|
+
**Functional Components (Modern React):**
|
|
59
|
+
```jsx
|
|
60
|
+
DO:
|
|
61
|
+
✓ Use functional components with hooks
|
|
62
|
+
✓ Keep components small and focused
|
|
63
|
+
✓ Extract reusable logic into custom hooks
|
|
64
|
+
✓ Use descriptive component names
|
|
65
|
+
✓ Separate logic from presentation
|
|
66
|
+
|
|
67
|
+
DON'T:
|
|
68
|
+
✗ Use class components (legacy pattern)
|
|
69
|
+
✗ Create mega-components (split them)
|
|
70
|
+
✗ Inline complex logic in JSX
|
|
71
|
+
✗ Forget to memoize expensive components
|
|
72
|
+
✗ Nest component definitions
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Component Composition:**
|
|
76
|
+
```jsx
|
|
77
|
+
DO:
|
|
78
|
+
✓ Compose small components into larger ones
|
|
79
|
+
✓ Use children prop for flexible composition
|
|
80
|
+
✓ Pass components as props when needed
|
|
81
|
+
✓ Use render props for advanced patterns
|
|
82
|
+
✓ Implement compound components for related UI
|
|
83
|
+
|
|
84
|
+
DON'T:
|
|
85
|
+
✗ Prop drill through many levels (use Context)
|
|
86
|
+
✗ Over-abstract too early
|
|
87
|
+
✗ Create deep component hierarchies
|
|
88
|
+
✗ Duplicate logic across components
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Hooks Best Practices
|
|
92
|
+
|
|
93
|
+
**useState:**
|
|
94
|
+
```jsx
|
|
95
|
+
DO:
|
|
96
|
+
✓ Use separate state variables for unrelated data
|
|
97
|
+
✓ Update state immutably (spread operator, map, filter)
|
|
98
|
+
✓ Use functional updates when referencing previous state
|
|
99
|
+
✓ Initialize state correctly (lazy initialization for expensive ops)
|
|
100
|
+
|
|
101
|
+
DON'T:
|
|
102
|
+
✗ Mutate state directly (array.push, object.property = value)
|
|
103
|
+
✗ Store derived values in state (calculate from existing state)
|
|
104
|
+
✗ Use one giant state object
|
|
105
|
+
✗ Forget that setState is asynchronous
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**useEffect:**
|
|
109
|
+
```jsx
|
|
110
|
+
DO:
|
|
111
|
+
✓ Include all dependencies in dependency array
|
|
112
|
+
✓ Return cleanup function when needed
|
|
113
|
+
✓ Keep effects focused (one concern per effect)
|
|
114
|
+
✓ Use empty array [] for mount-only effects
|
|
115
|
+
✓ Use ESLint exhaustive-deps rule
|
|
116
|
+
|
|
117
|
+
DON'T:
|
|
118
|
+
✗ Omit dependencies (stale closures)
|
|
119
|
+
✗ Use effects for derived state (use useMemo)
|
|
120
|
+
✗ Create infinite loops (missing deps, setState without condition)
|
|
121
|
+
✗ Forget to cleanup (event listeners, subscriptions, timers)
|
|
122
|
+
✗ Use effects for event handlers (use onClick, etc.)
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**useCallback & useMemo:**
|
|
126
|
+
```jsx
|
|
127
|
+
DO:
|
|
128
|
+
✓ Memoize callbacks passed to child components
|
|
129
|
+
✓ Memoize expensive computations
|
|
130
|
+
✓ Include all dependencies
|
|
131
|
+
✓ Use for performance optimization, not default
|
|
132
|
+
|
|
133
|
+
DON'T:
|
|
134
|
+
✗ Overuse (premature optimization)
|
|
135
|
+
✗ Memoize everything (adds overhead)
|
|
136
|
+
✗ Forget dependencies
|
|
137
|
+
✗ Use for cheap operations
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**Custom Hooks:**
|
|
141
|
+
```jsx
|
|
142
|
+
DO:
|
|
143
|
+
✓ Start name with "use" (useAuth, useForm, useFetch)
|
|
144
|
+
✓ Extract reusable logic
|
|
145
|
+
✓ Return arrays [value, setter] or objects {value, actions}
|
|
146
|
+
✓ Keep hooks composable
|
|
147
|
+
✓ Handle cleanup properly
|
|
148
|
+
|
|
149
|
+
DON'T:
|
|
150
|
+
✗ Call hooks conditionally (breaks Rules of Hooks)
|
|
151
|
+
✗ Call hooks in loops or nested functions
|
|
152
|
+
✗ Make hooks too specific (hard to reuse)
|
|
153
|
+
✗ Return too many values (destructuring nightmare)
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### State Management
|
|
157
|
+
|
|
158
|
+
**Local State (useState):**
|
|
159
|
+
```jsx
|
|
160
|
+
When: Component-specific, not shared
|
|
161
|
+
Example: Form inputs, toggles, counters
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**Lifted State:**
|
|
165
|
+
```jsx
|
|
166
|
+
When: Shared between siblings, shallow tree
|
|
167
|
+
Example: Parent managing child states
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
**Context API:**
|
|
171
|
+
```jsx
|
|
172
|
+
When: Global or feature-level state
|
|
173
|
+
Example: Auth, theme, language
|
|
174
|
+
DO:
|
|
175
|
+
✓ Split contexts by concern (AuthContext, ThemeContext)
|
|
176
|
+
✓ Memoize context values
|
|
177
|
+
✓ Use separate contexts for data and actions
|
|
178
|
+
✓ Provide at appropriate level (not always root)
|
|
179
|
+
|
|
180
|
+
DON'T:
|
|
181
|
+
✗ Use for all state (performance issues)
|
|
182
|
+
✗ Put frequently changing values in context
|
|
183
|
+
✗ Create one giant context
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
**External Libraries:**
|
|
187
|
+
```jsx
|
|
188
|
+
When: Complex state logic, advanced needs
|
|
189
|
+
Options:
|
|
190
|
+
- Redux Toolkit: Large apps, complex state, DevTools
|
|
191
|
+
- Zustand: Simple, minimal boilerplate
|
|
192
|
+
- Jotai/Recoil: Atomic state management
|
|
193
|
+
- TanStack Query: Server state (API calls, caching)
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Performance Optimization
|
|
197
|
+
|
|
198
|
+
**React.memo:**
|
|
199
|
+
```jsx
|
|
200
|
+
DO:
|
|
201
|
+
✓ Memoize expensive components
|
|
202
|
+
✓ Use when props rarely change
|
|
203
|
+
✓ Provide custom comparison function if needed
|
|
204
|
+
|
|
205
|
+
DON'T:
|
|
206
|
+
✗ Wrap every component (overhead)
|
|
207
|
+
✗ Use without profiling first
|
|
208
|
+
✗ Forget to memoize props (objects, arrays, functions)
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**Code Splitting:**
|
|
212
|
+
```jsx
|
|
213
|
+
DO:
|
|
214
|
+
✓ Use React.lazy() for route-based splitting
|
|
215
|
+
✓ Use dynamic import() for large components
|
|
216
|
+
✓ Show Suspense fallback
|
|
217
|
+
✓ Split by routes first, then by features
|
|
218
|
+
|
|
219
|
+
DON'T:
|
|
220
|
+
✗ Split too aggressively (too many chunks)
|
|
221
|
+
✗ Split small components
|
|
222
|
+
✗ Forget error boundaries
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
**Lists & Keys:**
|
|
226
|
+
```jsx
|
|
227
|
+
DO:
|
|
228
|
+
✓ Use stable, unique keys (IDs from data)
|
|
229
|
+
✓ Keep key at the mapped element
|
|
230
|
+
✓ Use index only for static lists
|
|
231
|
+
|
|
232
|
+
DON'T:
|
|
233
|
+
✗ Use array index for dynamic lists (bugs on reorder)
|
|
234
|
+
✗ Use random keys (breaks reconciliation)
|
|
235
|
+
✗ Omit keys (warning + performance issues)
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Forms & Controlled Components
|
|
239
|
+
|
|
240
|
+
```jsx
|
|
241
|
+
DO:
|
|
242
|
+
✓ Use controlled components (value + onChange)
|
|
243
|
+
✓ Validate on blur or submit (not every keystroke)
|
|
244
|
+
✓ Use form libraries for complex forms (React Hook Form, Formik)
|
|
245
|
+
✓ Debounce expensive validations
|
|
246
|
+
✓ Show clear error messages
|
|
247
|
+
|
|
248
|
+
DON'T:
|
|
249
|
+
✗ Use uncontrolled components unless necessary
|
|
250
|
+
✗ Validate on every keystroke (performance)
|
|
251
|
+
✗ Forget to prevent default on form submit
|
|
252
|
+
✗ Store all form state in parent (use form libraries)
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Error Handling
|
|
256
|
+
|
|
257
|
+
```jsx
|
|
258
|
+
DO:
|
|
259
|
+
✓ Use Error Boundaries for component errors
|
|
260
|
+
✓ Implement fallback UI
|
|
261
|
+
✓ Log errors to monitoring service
|
|
262
|
+
✓ Handle async errors in try/catch
|
|
263
|
+
✓ Show user-friendly error messages
|
|
264
|
+
|
|
265
|
+
DON'T:
|
|
266
|
+
✗ Catch all errors silently
|
|
267
|
+
✗ Show technical errors to users
|
|
268
|
+
✗ Forget to handle promise rejections
|
|
269
|
+
✗ Rely on Error Boundaries for async (they don't catch those)
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
## Anti-Patterns
|
|
273
|
+
|
|
274
|
+
### Common Mistakes
|
|
275
|
+
|
|
276
|
+
```jsx
|
|
277
|
+
❌ Inline object/array in JSX (causes re-renders)
|
|
278
|
+
<Component config={{}} items={[]} />
|
|
279
|
+
|
|
280
|
+
✅ Define outside or useMemo
|
|
281
|
+
const config = useMemo(() => ({}), [])
|
|
282
|
+
|
|
283
|
+
❌ Derived state
|
|
284
|
+
const [fullName, setFullName] = useState('')
|
|
285
|
+
// Calculated from firstName + lastName
|
|
286
|
+
|
|
287
|
+
✅ Compute during render
|
|
288
|
+
const fullName = `${firstName} ${lastName}`
|
|
289
|
+
|
|
290
|
+
❌ Prop drilling
|
|
291
|
+
<A> → <B prop={x}> → <C prop={x}> → <D prop={x}> → <E prop={x}>
|
|
292
|
+
|
|
293
|
+
✅ Context or composition
|
|
294
|
+
<Context.Provider value={x}>
|
|
295
|
+
<A><B><C><D><E /></D></C></B></A>
|
|
296
|
+
</Context.Provider>
|
|
297
|
+
|
|
298
|
+
❌ Mutating state
|
|
299
|
+
items.push(newItem)
|
|
300
|
+
setItems(items)
|
|
301
|
+
|
|
302
|
+
✅ Immutable updates
|
|
303
|
+
setItems([...items, newItem])
|
|
304
|
+
|
|
305
|
+
❌ useEffect for event handlers
|
|
306
|
+
useEffect(() => {
|
|
307
|
+
button.addEventListener('click', handler)
|
|
308
|
+
}, [])
|
|
309
|
+
|
|
310
|
+
✅ Direct event handler
|
|
311
|
+
<button onClick={handler}>
|
|
312
|
+
|
|
313
|
+
❌ Forgetting dependencies
|
|
314
|
+
useEffect(() => {
|
|
315
|
+
fetchData(userId)
|
|
316
|
+
}, []) // Missing userId
|
|
317
|
+
|
|
318
|
+
✅ Include all deps
|
|
319
|
+
useEffect(() => {
|
|
320
|
+
fetchData(userId)
|
|
321
|
+
}, [userId])
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
## For /dev-specs
|
|
325
|
+
|
|
326
|
+
When writing specs for React projects:
|
|
327
|
+
|
|
328
|
+
**Component Specs:**
|
|
329
|
+
- Define component props and types
|
|
330
|
+
- Specify state management approach (local, Context, external)
|
|
331
|
+
- Identify if memoization needed
|
|
332
|
+
- Note if code splitting required
|
|
333
|
+
- Specify form handling approach
|
|
334
|
+
|
|
335
|
+
**State Management:**
|
|
336
|
+
- Clarify scope (local, feature, global)
|
|
337
|
+
- If Context: specify provider location
|
|
338
|
+
- If external library: specify which one
|
|
339
|
+
|
|
340
|
+
**Performance Requirements:**
|
|
341
|
+
- List optimization needs (memo, lazy, useMemo)
|
|
342
|
+
- Specify bundle size constraints
|
|
343
|
+
|
|
344
|
+
**Patterns to Use:**
|
|
345
|
+
- Custom hooks for reusable logic
|
|
346
|
+
- Compound components for related UI
|
|
347
|
+
- Render props for advanced patterns
|
|
348
|
+
|
|
349
|
+
## For /dev-coding
|
|
350
|
+
|
|
351
|
+
When implementing React features:
|
|
352
|
+
|
|
353
|
+
### 1. Component Creation
|
|
354
|
+
|
|
355
|
+
**Start with:**
|
|
356
|
+
- Read tech-context.md for project's React patterns
|
|
357
|
+
- Check if TypeScript is used
|
|
358
|
+
- Identify state management approach
|
|
359
|
+
- Check for component library (MUI, Chakra, Ant Design, shadcn/ui)
|
|
360
|
+
|
|
361
|
+
**Structure:**
|
|
362
|
+
```jsx
|
|
363
|
+
// Component.tsx
|
|
364
|
+
import { useState, useEffect } from 'react'
|
|
365
|
+
|
|
366
|
+
interface ComponentProps {
|
|
367
|
+
// Props with TypeScript
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
export function Component({ prop1, prop2 }: ComponentProps) {
|
|
371
|
+
// 1. Hooks (useState, useEffect, useContext, custom hooks)
|
|
372
|
+
const [state, setState] = useState(initial)
|
|
373
|
+
|
|
374
|
+
// 2. Derived values (useMemo)
|
|
375
|
+
const derived = useMemo(() => compute(state), [state])
|
|
376
|
+
|
|
377
|
+
// 3. Callbacks (useCallback)
|
|
378
|
+
const handleClick = useCallback(() => {
|
|
379
|
+
// Handler logic
|
|
380
|
+
}, [dependencies])
|
|
381
|
+
|
|
382
|
+
// 4. Effects (useEffect)
|
|
383
|
+
useEffect(() => {
|
|
384
|
+
// Effect logic
|
|
385
|
+
return () => cleanup()
|
|
386
|
+
}, [dependencies])
|
|
387
|
+
|
|
388
|
+
// 5. Early returns (loading, error)
|
|
389
|
+
if (loading) return <Spinner />
|
|
390
|
+
if (error) return <Error />
|
|
391
|
+
|
|
392
|
+
// 6. Render
|
|
393
|
+
return (
|
|
394
|
+
<div>
|
|
395
|
+
{/* JSX */}
|
|
396
|
+
</div>
|
|
397
|
+
)
|
|
398
|
+
}
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
### 2. State Management
|
|
402
|
+
|
|
403
|
+
**Choose based on scope:**
|
|
404
|
+
- **Local UI state** → useState
|
|
405
|
+
- **Shared between siblings** → Lift state
|
|
406
|
+
- **Feature-level** → Context or custom hook
|
|
407
|
+
- **Global** → Context or external library
|
|
408
|
+
- **Server data** → TanStack Query
|
|
409
|
+
|
|
410
|
+
### 3. Performance
|
|
411
|
+
|
|
412
|
+
**Profile first, then optimize:**
|
|
413
|
+
- Use React DevTools Profiler
|
|
414
|
+
- Check for unnecessary re-renders
|
|
415
|
+
- Apply React.memo selectively
|
|
416
|
+
- Memoize callbacks and expensive computations
|
|
417
|
+
- Lazy load heavy components
|
|
418
|
+
|
|
419
|
+
### 4. Hooks Order
|
|
420
|
+
|
|
421
|
+
**Always call in same order:**
|
|
422
|
+
1. useState
|
|
423
|
+
2. useContext
|
|
424
|
+
3. Custom hooks
|
|
425
|
+
4. useMemo
|
|
426
|
+
5. useCallback
|
|
427
|
+
6. useEffect
|
|
428
|
+
7. useLayoutEffect (rare)
|
|
429
|
+
|
|
430
|
+
### 5. Common Patterns
|
|
431
|
+
|
|
432
|
+
**Fetch data:**
|
|
433
|
+
```jsx
|
|
434
|
+
const [data, setData] = useState(null)
|
|
435
|
+
const [loading, setLoading] = useState(true)
|
|
436
|
+
const [error, setError] = useState(null)
|
|
437
|
+
|
|
438
|
+
useEffect(() => {
|
|
439
|
+
let cancelled = false
|
|
440
|
+
|
|
441
|
+
async function fetchData() {
|
|
442
|
+
try {
|
|
443
|
+
const result = await api.get(url)
|
|
444
|
+
if (!cancelled) setData(result)
|
|
445
|
+
} catch (err) {
|
|
446
|
+
if (!cancelled) setError(err)
|
|
447
|
+
} finally {
|
|
448
|
+
if (!cancelled) setLoading(false)
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
fetchData()
|
|
453
|
+
return () => { cancelled = true }
|
|
454
|
+
}, [url])
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
**Custom hook:**
|
|
458
|
+
```jsx
|
|
459
|
+
function useAuth() {
|
|
460
|
+
const [user, setUser] = useState(null)
|
|
461
|
+
const [loading, setLoading] = useState(true)
|
|
462
|
+
|
|
463
|
+
useEffect(() => {
|
|
464
|
+
const unsubscribe = auth.onAuthStateChanged(setUser)
|
|
465
|
+
setLoading(false)
|
|
466
|
+
return unsubscribe
|
|
467
|
+
}, [])
|
|
468
|
+
|
|
469
|
+
return { user, loading }
|
|
470
|
+
}
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
## For /dev-review
|
|
474
|
+
|
|
475
|
+
When reviewing React code:
|
|
476
|
+
|
|
477
|
+
**Component Quality:**
|
|
478
|
+
- [ ] Components are small and focused (< 300 lines)
|
|
479
|
+
- [ ] Props are typed (TypeScript interfaces)
|
|
480
|
+
- [ ] No prop drilling (max 2-3 levels)
|
|
481
|
+
- [ ] Meaningful component and prop names
|
|
482
|
+
|
|
483
|
+
**Hooks Usage:**
|
|
484
|
+
- [ ] Hooks follow Rules of Hooks (top level, order)
|
|
485
|
+
- [ ] All dependencies included in arrays
|
|
486
|
+
- [ ] No infinite loops in useEffect
|
|
487
|
+
- [ ] Cleanup functions where needed
|
|
488
|
+
- [ ] Custom hooks for reusable logic
|
|
489
|
+
|
|
490
|
+
**State Management:**
|
|
491
|
+
- [ ] No derived state (calculate from existing)
|
|
492
|
+
- [ ] State updates are immutable
|
|
493
|
+
- [ ] Appropriate scope (local vs lifted vs global)
|
|
494
|
+
- [ ] Context not overused (performance)
|
|
495
|
+
|
|
496
|
+
**Performance:**
|
|
497
|
+
- [ ] No inline object/array creation in renders
|
|
498
|
+
- [ ] Expensive operations memoized
|
|
499
|
+
- [ ] Large components lazy loaded
|
|
500
|
+
- [ ] Lists have stable keys
|
|
501
|
+
|
|
502
|
+
**JSX Quality:**
|
|
503
|
+
- [ ] No complex logic in JSX (extract to functions)
|
|
504
|
+
- [ ] Conditional rendering is clear
|
|
505
|
+
- [ ] Event handlers are memoized if needed
|
|
506
|
+
- [ ] Accessibility attributes present (aria-*, alt, etc.)
|
|
507
|
+
|
|
508
|
+
**Error Handling:**
|
|
509
|
+
- [ ] Error boundaries implemented
|
|
510
|
+
- [ ] Async errors caught (try/catch)
|
|
511
|
+
- [ ] User-friendly error messages
|
|
512
|
+
- [ ] Loading states shown
|
|
513
|
+
|
|
514
|
+
**Testing:**
|
|
515
|
+
- [ ] Components are testable (no tight coupling)
|
|
516
|
+
- [ ] Logic extracted to pure functions
|
|
517
|
+
- [ ] Hooks are testable (custom hooks especially)
|
|
518
|
+
|
|
519
|
+
## Integration with Other Stacks
|
|
520
|
+
|
|
521
|
+
**React + Next.js:**
|
|
522
|
+
- Follow Next.js App Router conventions
|
|
523
|
+
- Use Server Components by default
|
|
524
|
+
- Add "use client" only when needed
|
|
525
|
+
- Leverage Next.js data fetching
|
|
526
|
+
|
|
527
|
+
**React + Vite:**
|
|
528
|
+
- Fast dev server
|
|
529
|
+
- Modern build tool
|
|
530
|
+
- Use Vite plugins ecosystem
|
|
531
|
+
|
|
532
|
+
**React + TypeScript:**
|
|
533
|
+
- Define prop types with interfaces
|
|
534
|
+
- Use React.FC sparingly (prefer typed props)
|
|
535
|
+
- Leverage type inference
|
|
536
|
+
- Use generics for reusable components
|
|
537
|
+
|
|
538
|
+
**React + Tailwind CSS:**
|
|
539
|
+
- Use utility-first classes
|
|
540
|
+
- Extract components for repeated patterns
|
|
541
|
+
- Use @apply for common combinations
|
|
542
|
+
- Leverage Tailwind's JIT mode
|
|
543
|
+
|
|
544
|
+
**React + State Libraries:**
|
|
545
|
+
- Redux Toolkit: Use createSlice, RTK Query
|
|
546
|
+
- Zustand: Simple store creation
|
|
547
|
+
- TanStack Query: Server state management, caching
|
|
548
|
+
|
|
549
|
+
## Common Gotchas
|
|
550
|
+
|
|
551
|
+
1. **Stale Closures**: Missing dependencies in useEffect/useCallback
|
|
552
|
+
2. **Infinite Loops**: setState in useEffect without deps or condition
|
|
553
|
+
3. **Key Prop**: Using index for dynamic lists
|
|
554
|
+
4. **Object/Array Identity**: Creating new objects in render
|
|
555
|
+
5. **Async setState**: Setting state is asynchronous, not immediate
|
|
556
|
+
6. **Rules of Hooks**: Must call unconditionally, same order every render
|
|
557
|
+
7. **Event Handler Scope**: this binding (use arrow functions)
|
|
558
|
+
8. **useEffect Cleanup**: Not cleaning up subscriptions/listeners
|
|
559
|
+
|
|
560
|
+
## React 18+ Features
|
|
561
|
+
|
|
562
|
+
**Concurrent Features:**
|
|
563
|
+
- Automatic batching (multiple setStates batch automatically)
|
|
564
|
+
- Transitions (mark updates as non-urgent with startTransition)
|
|
565
|
+
- Suspense (data fetching, lazy loading)
|
|
566
|
+
- Streaming SSR (progressive HTML rendering)
|
|
567
|
+
|
|
568
|
+
**New Hooks:**
|
|
569
|
+
- useId (unique IDs for accessibility)
|
|
570
|
+
- useTransition (mark non-urgent updates)
|
|
571
|
+
- useDeferredValue (defer updates for performance)
|
|
572
|
+
- useSyncExternalStore (external store integration)
|
|
573
|
+
|
|
574
|
+
## Resources
|
|
575
|
+
|
|
576
|
+
- [React Docs](https://react.dev) - Official documentation
|
|
577
|
+
- [React DevTools](https://react.dev/learn/react-developer-tools) - Browser extension
|
|
578
|
+
- [Rules of Hooks](https://react.dev/reference/rules/rules-of-hooks) - Hook constraints
|
|
579
|
+
- [React TypeScript Cheatsheet](https://react-typescript-cheatsheet.netlify.app) - TS patterns
|
package/package.json
CHANGED
package/skills/_registry.md
CHANGED
|
@@ -180,9 +180,10 @@ Technical knowledge - HOW to build with specific tools:
|
|
|
180
180
|
|
|
181
181
|
| Stack | Folder | Type |
|
|
182
182
|
|-------|--------|------|
|
|
183
|
-
|
|
|
184
|
-
| Nuxt.js | `stacks/nuxt/` | Vue + SSR Framework |
|
|
183
|
+
| React | `stacks/react/` | UI Library |
|
|
185
184
|
| Next.js | `stacks/nextjs/` | React + SSR Framework |
|
|
185
|
+
| Nuxt.js | `stacks/nuxt/` | Vue + SSR Framework |
|
|
186
|
+
| Directus | `stacks/directus/` | Backend BaaS |
|
|
186
187
|
|
|
187
188
|
**Folder structure:**
|
|
188
189
|
```
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: dev-coding
|
|
3
3
|
description: Implement features as a Principal Engineering Developer
|
|
4
|
-
version: 2.1.
|
|
4
|
+
version: 2.1.2
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# /dev-coding - Implementation Skill
|
|
@@ -67,6 +67,7 @@ You have three layers of knowledge to apply:
|
|
|
67
67
|
3. **Focus on "For /dev-coding" section** → Note best practices
|
|
68
68
|
|
|
69
69
|
**Stack file mapping:**
|
|
70
|
+
- "React" → `knowledge/stacks/react/_index.md`
|
|
70
71
|
- "Next.js" → `knowledge/stacks/nextjs/_index.md`
|
|
71
72
|
- "Nuxt" → `knowledge/stacks/nuxt/_index.md`
|
|
72
73
|
- "Directus" → `knowledge/stacks/directus/_index.md`
|
|
@@ -176,6 +177,7 @@ Implementation
|
|
|
176
177
|
```
|
|
177
178
|
|
|
178
179
|
2. **Load stack knowledge files:**
|
|
180
|
+
- If "React" detected → Read `knowledge/stacks/react/_index.md`
|
|
179
181
|
- If "Next.js" detected → Read `knowledge/stacks/nextjs/_index.md`
|
|
180
182
|
- If "Nuxt" detected → Read `knowledge/stacks/nuxt/_index.md`
|
|
181
183
|
- If "Directus" detected → Read `knowledge/stacks/directus/_index.md`
|
|
@@ -334,6 +336,7 @@ Implementation successful when:
|
|
|
334
336
|
- `references/frontend-principles.md` - General UI, component, state principles
|
|
335
337
|
|
|
336
338
|
**Layer 2 - Framework:**
|
|
339
|
+
- `knowledge/stacks/react/_index.md` - React patterns (Hooks, Context, performance)
|
|
337
340
|
- `knowledge/stacks/nextjs/_index.md` - Next.js patterns (Server Actions, App Router, RSC)
|
|
338
341
|
- `knowledge/stacks/nuxt/_index.md` - Nuxt patterns (composables, Nuxt UI, SSR)
|
|
339
342
|
- `knowledge/stacks/directus/_index.md` - Directus patterns (collections, flows, extensions)
|