red64-cli 0.1.0 → 0.2.0

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.
Files changed (103) hide show
  1. package/dist/cli/parseArgs.d.ts.map +1 -1
  2. package/dist/cli/parseArgs.js +5 -0
  3. package/dist/cli/parseArgs.js.map +1 -1
  4. package/dist/components/init/CompleteStep.d.ts.map +1 -1
  5. package/dist/components/init/CompleteStep.js +2 -2
  6. package/dist/components/init/CompleteStep.js.map +1 -1
  7. package/dist/components/init/TestCheckStep.d.ts +16 -0
  8. package/dist/components/init/TestCheckStep.d.ts.map +1 -0
  9. package/dist/components/init/TestCheckStep.js +120 -0
  10. package/dist/components/init/TestCheckStep.js.map +1 -0
  11. package/dist/components/init/index.d.ts +1 -0
  12. package/dist/components/init/index.d.ts.map +1 -1
  13. package/dist/components/init/index.js +1 -0
  14. package/dist/components/init/index.js.map +1 -1
  15. package/dist/components/init/types.d.ts +9 -0
  16. package/dist/components/init/types.d.ts.map +1 -1
  17. package/dist/components/screens/InitScreen.d.ts.map +1 -1
  18. package/dist/components/screens/InitScreen.js +69 -6
  19. package/dist/components/screens/InitScreen.js.map +1 -1
  20. package/dist/components/screens/StartScreen.d.ts.map +1 -1
  21. package/dist/components/screens/StartScreen.js +89 -3
  22. package/dist/components/screens/StartScreen.js.map +1 -1
  23. package/dist/services/ConfigService.d.ts +1 -0
  24. package/dist/services/ConfigService.d.ts.map +1 -1
  25. package/dist/services/ConfigService.js.map +1 -1
  26. package/dist/services/ProjectDetector.d.ts +28 -0
  27. package/dist/services/ProjectDetector.d.ts.map +1 -0
  28. package/dist/services/ProjectDetector.js +236 -0
  29. package/dist/services/ProjectDetector.js.map +1 -0
  30. package/dist/services/TestRunner.d.ts +46 -0
  31. package/dist/services/TestRunner.d.ts.map +1 -0
  32. package/dist/services/TestRunner.js +85 -0
  33. package/dist/services/TestRunner.js.map +1 -0
  34. package/dist/services/index.d.ts +2 -0
  35. package/dist/services/index.d.ts.map +1 -1
  36. package/dist/services/index.js +2 -0
  37. package/dist/services/index.js.map +1 -1
  38. package/dist/types/index.d.ts +1 -0
  39. package/dist/types/index.d.ts.map +1 -1
  40. package/dist/types/index.js.map +1 -1
  41. package/framework/agents/claude/.claude/agents/red64/spec-impl.md +131 -2
  42. package/framework/agents/claude/.claude/commands/red64/spec-impl.md +24 -0
  43. package/framework/agents/codex/.codex/agents/red64/spec-impl.md +131 -2
  44. package/framework/agents/codex/.codex/commands/red64/spec-impl.md +24 -0
  45. package/framework/stacks/generic/feedback.md +80 -0
  46. package/framework/stacks/nextjs/accessibility.md +437 -0
  47. package/framework/stacks/nextjs/api.md +431 -0
  48. package/framework/stacks/nextjs/coding-style.md +282 -0
  49. package/framework/stacks/nextjs/commenting.md +226 -0
  50. package/framework/stacks/nextjs/components.md +411 -0
  51. package/framework/stacks/nextjs/conventions.md +333 -0
  52. package/framework/stacks/nextjs/css.md +310 -0
  53. package/framework/stacks/nextjs/error-handling.md +442 -0
  54. package/framework/stacks/nextjs/feedback.md +124 -0
  55. package/framework/stacks/nextjs/migrations.md +332 -0
  56. package/framework/stacks/nextjs/models.md +362 -0
  57. package/framework/stacks/nextjs/queries.md +410 -0
  58. package/framework/stacks/nextjs/responsive.md +338 -0
  59. package/framework/stacks/nextjs/tech-stack.md +177 -0
  60. package/framework/stacks/nextjs/test-writing.md +475 -0
  61. package/framework/stacks/nextjs/validation.md +467 -0
  62. package/framework/stacks/python/api.md +468 -0
  63. package/framework/stacks/python/authentication.md +342 -0
  64. package/framework/stacks/python/code-quality.md +283 -0
  65. package/framework/stacks/python/code-refactoring.md +315 -0
  66. package/framework/stacks/python/coding-style.md +462 -0
  67. package/framework/stacks/python/conventions.md +399 -0
  68. package/framework/stacks/python/error-handling.md +512 -0
  69. package/framework/stacks/python/feedback.md +92 -0
  70. package/framework/stacks/python/implement-ai-llm.md +468 -0
  71. package/framework/stacks/python/migrations.md +388 -0
  72. package/framework/stacks/python/models.md +399 -0
  73. package/framework/stacks/python/python.md +232 -0
  74. package/framework/stacks/python/queries.md +451 -0
  75. package/framework/stacks/python/structure.md +245 -58
  76. package/framework/stacks/python/tech.md +92 -35
  77. package/framework/stacks/python/testing.md +380 -0
  78. package/framework/stacks/python/validation.md +471 -0
  79. package/framework/stacks/rails/authentication.md +176 -0
  80. package/framework/stacks/rails/code-quality.md +287 -0
  81. package/framework/stacks/rails/code-refactoring.md +299 -0
  82. package/framework/stacks/rails/feedback.md +130 -0
  83. package/framework/stacks/rails/implement-ai-llm-with-rubyllm.md +342 -0
  84. package/framework/stacks/rails/rails.md +301 -0
  85. package/framework/stacks/rails/rails8-best-practices.md +498 -0
  86. package/framework/stacks/rails/rails8-css.md +573 -0
  87. package/framework/stacks/rails/structure.md +140 -0
  88. package/framework/stacks/rails/tech.md +108 -0
  89. package/framework/stacks/react/code-quality.md +521 -0
  90. package/framework/stacks/react/components.md +625 -0
  91. package/framework/stacks/react/data-fetching.md +586 -0
  92. package/framework/stacks/react/feedback.md +110 -0
  93. package/framework/stacks/react/forms.md +694 -0
  94. package/framework/stacks/react/performance.md +640 -0
  95. package/framework/stacks/react/product.md +22 -9
  96. package/framework/stacks/react/state-management.md +472 -0
  97. package/framework/stacks/react/structure.md +351 -44
  98. package/framework/stacks/react/tech.md +219 -30
  99. package/framework/stacks/react/testing.md +690 -0
  100. package/package.json +1 -1
  101. package/framework/stacks/node/product.md +0 -27
  102. package/framework/stacks/node/structure.md +0 -82
  103. package/framework/stacks/node/tech.md +0 -63
@@ -0,0 +1,640 @@
1
+ # Performance Patterns
2
+
3
+ React performance optimization patterns for fast, responsive applications.
4
+
5
+ ---
6
+
7
+ ## Philosophy
8
+
9
+ - **Measure first**: Don't optimize without profiling; intuition is often wrong
10
+ - **Optimize selectively**: Focus on actual bottlenecks, not hypothetical ones
11
+ - **User perception matters**: 100ms feels instant, 300ms feels responsive
12
+ - **Bundle size is performance**: Every KB counts on slow connections
13
+
14
+ ---
15
+
16
+ ## Performance Priorities
17
+
18
+ 1. **Initial load time**: Time to First Contentful Paint (FCP)
19
+ 2. **Time to Interactive (TTI)**: When users can interact
20
+ 3. **Runtime performance**: Smooth 60fps interactions
21
+ 4. **Memory usage**: Avoid leaks, minimize footprint
22
+
23
+ ---
24
+
25
+ ## Code Splitting
26
+
27
+ ### Route-Level Splitting (Essential)
28
+
29
+ ```typescript
30
+ // app/routes.tsx
31
+ import { lazy, Suspense } from 'react';
32
+ import { createBrowserRouter } from 'react-router-dom';
33
+
34
+ // Lazy load route components
35
+ const Dashboard = lazy(() => import('@/features/dashboard/pages/Dashboard'));
36
+ const Users = lazy(() => import('@/features/users/pages/Users'));
37
+ const Settings = lazy(() => import('@/features/settings/pages/Settings'));
38
+
39
+ // Loading fallback
40
+ function PageLoader() {
41
+ return (
42
+ <div className="flex h-full items-center justify-center">
43
+ <Spinner size="lg" />
44
+ </div>
45
+ );
46
+ }
47
+
48
+ export const router = createBrowserRouter([
49
+ {
50
+ path: '/',
51
+ element: <Layout />,
52
+ children: [
53
+ {
54
+ path: 'dashboard',
55
+ element: (
56
+ <Suspense fallback={<PageLoader />}>
57
+ <Dashboard />
58
+ </Suspense>
59
+ ),
60
+ },
61
+ {
62
+ path: 'users/*',
63
+ element: (
64
+ <Suspense fallback={<PageLoader />}>
65
+ <Users />
66
+ </Suspense>
67
+ ),
68
+ },
69
+ {
70
+ path: 'settings',
71
+ element: (
72
+ <Suspense fallback={<PageLoader />}>
73
+ <Settings />
74
+ </Suspense>
75
+ ),
76
+ },
77
+ ],
78
+ },
79
+ ]);
80
+ ```
81
+
82
+ ### Component-Level Splitting
83
+
84
+ ```typescript
85
+ // Split heavy components
86
+ const Chart = lazy(() => import('@/components/Chart'));
87
+ const RichTextEditor = lazy(() => import('@/components/RichTextEditor'));
88
+ const CodeEditor = lazy(() => import('@/components/CodeEditor'));
89
+
90
+ function Dashboard() {
91
+ return (
92
+ <div>
93
+ <h1>Dashboard</h1>
94
+ <Suspense fallback={<ChartSkeleton />}>
95
+ <Chart data={data} />
96
+ </Suspense>
97
+ </div>
98
+ );
99
+ }
100
+ ```
101
+
102
+ ### Named Exports with Lazy
103
+
104
+ ```typescript
105
+ // For named exports, use intermediate module
106
+ // components/Chart/index.ts
107
+ export { Chart } from './Chart';
108
+
109
+ // Lazy import
110
+ const Chart = lazy(() =>
111
+ import('@/components/Chart').then((module) => ({ default: module.Chart }))
112
+ );
113
+ ```
114
+
115
+ ---
116
+
117
+ ## Memoization
118
+
119
+ ### When to Use React.memo
120
+
121
+ ```typescript
122
+ // Use memo when:
123
+ // 1. Component renders often with same props
124
+ // 2. Component is expensive to render
125
+ // 3. Parent re-renders frequently
126
+
127
+ // Good candidate: Pure display component rendered in a list
128
+ const UserCard = memo(function UserCard({ user }: { user: User }) {
129
+ return (
130
+ <div className="user-card">
131
+ <Avatar src={user.avatar} alt={user.name} />
132
+ <h3>{user.name}</h3>
133
+ <p>{user.email}</p>
134
+ </div>
135
+ );
136
+ });
137
+
138
+ // Bad candidate: Simple component, renders rarely
139
+ // Don't memo this - overhead not worth it
140
+ function PageTitle({ title }: { title: string }) {
141
+ return <h1>{title}</h1>;
142
+ }
143
+ ```
144
+
145
+ ### useMemo for Expensive Computations
146
+
147
+ ```typescript
148
+ function DataTable({ data, sortBy, filters }: Props) {
149
+ // Expensive: filtering and sorting large dataset
150
+ const processedData = useMemo(() => {
151
+ let result = [...data];
152
+
153
+ // Filter
154
+ if (filters.status) {
155
+ result = result.filter((item) => item.status === filters.status);
156
+ }
157
+ if (filters.search) {
158
+ result = result.filter((item) =>
159
+ item.name.toLowerCase().includes(filters.search.toLowerCase())
160
+ );
161
+ }
162
+
163
+ // Sort
164
+ result.sort((a, b) => {
165
+ const aVal = a[sortBy.field];
166
+ const bVal = b[sortBy.field];
167
+ return sortBy.direction === 'asc'
168
+ ? aVal.localeCompare(bVal)
169
+ : bVal.localeCompare(aVal);
170
+ });
171
+
172
+ return result;
173
+ }, [data, sortBy, filters]); // Only recompute when these change
174
+
175
+ return <Table data={processedData} />;
176
+ }
177
+ ```
178
+
179
+ ### useCallback for Stable References
180
+
181
+ ```typescript
182
+ function ParentComponent() {
183
+ const [items, setItems] = useState<Item[]>([]);
184
+
185
+ // Without useCallback: new function every render
186
+ // Children with memo would still re-render
187
+ const handleDelete = useCallback((id: string) => {
188
+ setItems((prev) => prev.filter((item) => item.id !== id));
189
+ }, []); // Empty deps: function never changes
190
+
191
+ const handleUpdate = useCallback((id: string, data: Partial<Item>) => {
192
+ setItems((prev) =>
193
+ prev.map((item) => (item.id === id ? { ...item, ...data } : item))
194
+ );
195
+ }, []);
196
+
197
+ return (
198
+ <div>
199
+ {items.map((item) => (
200
+ <MemoizedItem
201
+ key={item.id}
202
+ item={item}
203
+ onDelete={handleDelete}
204
+ onUpdate={handleUpdate}
205
+ />
206
+ ))}
207
+ </div>
208
+ );
209
+ }
210
+ ```
211
+
212
+ ### When NOT to Memoize
213
+
214
+ ```typescript
215
+ // Don't memoize:
216
+
217
+ // 1. Simple/cheap computations
218
+ const fullName = `${user.firstName} ${user.lastName}`; // Just string concat
219
+
220
+ // 2. Primitives that change every render anyway
221
+ const now = new Date(); // Always new
222
+
223
+ // 3. Components that always receive new props
224
+ // If parent always creates new objects, memo is useless
225
+ <Child data={{ name: 'John' }} /> // New object every render
226
+
227
+ // 4. Components rendered once
228
+ function App() {
229
+ return <Layout />; // Only renders once
230
+ }
231
+ ```
232
+
233
+ ---
234
+
235
+ ## Virtualization
236
+
237
+ ### Long Lists with @tanstack/react-virtual
238
+
239
+ ```typescript
240
+ import { useVirtualizer } from '@tanstack/react-virtual';
241
+
242
+ function VirtualList({ items }: { items: Item[] }) {
243
+ const parentRef = useRef<HTMLDivElement>(null);
244
+
245
+ const virtualizer = useVirtualizer({
246
+ count: items.length,
247
+ getScrollElement: () => parentRef.current,
248
+ estimateSize: () => 50, // Estimated row height
249
+ overscan: 5, // Render 5 extra items above/below viewport
250
+ });
251
+
252
+ return (
253
+ <div
254
+ ref={parentRef}
255
+ className="h-[400px] overflow-auto"
256
+ >
257
+ <div
258
+ style={{
259
+ height: `${virtualizer.getTotalSize()}px`,
260
+ position: 'relative',
261
+ }}
262
+ >
263
+ {virtualizer.getVirtualItems().map((virtualItem) => (
264
+ <div
265
+ key={virtualItem.key}
266
+ style={{
267
+ position: 'absolute',
268
+ top: 0,
269
+ left: 0,
270
+ width: '100%',
271
+ height: `${virtualItem.size}px`,
272
+ transform: `translateY(${virtualItem.start}px)`,
273
+ }}
274
+ >
275
+ <ListItem item={items[virtualItem.index]} />
276
+ </div>
277
+ ))}
278
+ </div>
279
+ </div>
280
+ );
281
+ }
282
+ ```
283
+
284
+ ### When to Virtualize
285
+
286
+ | List Size | Recommendation |
287
+ |-----------|----------------|
288
+ | < 100 items | No virtualization needed |
289
+ | 100-500 items | Consider if items are complex |
290
+ | 500+ items | Definitely virtualize |
291
+
292
+ ---
293
+
294
+ ## Image Optimization
295
+
296
+ ### Lazy Loading Images
297
+
298
+ ```typescript
299
+ // Native lazy loading (modern browsers)
300
+ <img src={url} alt={alt} loading="lazy" />
301
+
302
+ // With intersection observer for more control
303
+ function LazyImage({ src, alt, ...props }: ImgProps) {
304
+ const [isLoaded, setIsLoaded] = useState(false);
305
+ const [isInView, setIsInView] = useState(false);
306
+ const imgRef = useRef<HTMLImageElement>(null);
307
+
308
+ useEffect(() => {
309
+ const observer = new IntersectionObserver(
310
+ ([entry]) => {
311
+ if (entry.isIntersecting) {
312
+ setIsInView(true);
313
+ observer.disconnect();
314
+ }
315
+ },
316
+ { rootMargin: '200px' } // Load 200px before in view
317
+ );
318
+
319
+ if (imgRef.current) {
320
+ observer.observe(imgRef.current);
321
+ }
322
+
323
+ return () => observer.disconnect();
324
+ }, []);
325
+
326
+ return (
327
+ <div ref={imgRef} className="relative">
328
+ {isInView && (
329
+ <img
330
+ src={src}
331
+ alt={alt}
332
+ onLoad={() => setIsLoaded(true)}
333
+ className={cn('transition-opacity', isLoaded ? 'opacity-100' : 'opacity-0')}
334
+ {...props}
335
+ />
336
+ )}
337
+ {!isLoaded && <Skeleton className="absolute inset-0" />}
338
+ </div>
339
+ );
340
+ }
341
+ ```
342
+
343
+ ### Responsive Images
344
+
345
+ ```typescript
346
+ <picture>
347
+ <source
348
+ srcSet="/image-400.webp 400w, /image-800.webp 800w, /image-1200.webp 1200w"
349
+ type="image/webp"
350
+ sizes="(max-width: 600px) 400px, (max-width: 1200px) 800px, 1200px"
351
+ />
352
+ <img
353
+ src="/image-800.jpg"
354
+ alt="Description"
355
+ loading="lazy"
356
+ decoding="async"
357
+ />
358
+ </picture>
359
+ ```
360
+
361
+ ---
362
+
363
+ ## Debouncing and Throttling
364
+
365
+ ### Debounce Search Input
366
+
367
+ ```typescript
368
+ import { useDebouncedValue } from '@/hooks/useDebouncedValue';
369
+
370
+ function SearchInput() {
371
+ const [query, setQuery] = useState('');
372
+ const debouncedQuery = useDebouncedValue(query, 300);
373
+
374
+ // API call uses debounced value
375
+ const { data } = useSearch(debouncedQuery);
376
+
377
+ return (
378
+ <input
379
+ value={query}
380
+ onChange={(e) => setQuery(e.target.value)}
381
+ placeholder="Search..."
382
+ />
383
+ );
384
+ }
385
+
386
+ // hooks/useDebouncedValue.ts
387
+ export function useDebouncedValue<T>(value: T, delay: number): T {
388
+ const [debouncedValue, setDebouncedValue] = useState(value);
389
+
390
+ useEffect(() => {
391
+ const timer = setTimeout(() => setDebouncedValue(value), delay);
392
+ return () => clearTimeout(timer);
393
+ }, [value, delay]);
394
+
395
+ return debouncedValue;
396
+ }
397
+ ```
398
+
399
+ ### Throttle Scroll Handler
400
+
401
+ ```typescript
402
+ import { useThrottle } from '@/hooks/useThrottle';
403
+
404
+ function ScrollTracker() {
405
+ const [scrollY, setScrollY] = useState(0);
406
+ const throttledScrollY = useThrottle(scrollY, 100);
407
+
408
+ useEffect(() => {
409
+ const handleScroll = () => setScrollY(window.scrollY);
410
+ window.addEventListener('scroll', handleScroll, { passive: true });
411
+ return () => window.removeEventListener('scroll', handleScroll);
412
+ }, []);
413
+
414
+ // Use throttledScrollY for expensive operations
415
+ useEffect(() => {
416
+ // This runs at most every 100ms
417
+ trackScrollPosition(throttledScrollY);
418
+ }, [throttledScrollY]);
419
+
420
+ return null;
421
+ }
422
+ ```
423
+
424
+ ---
425
+
426
+ ## State Updates Optimization
427
+
428
+ ### Batch Updates
429
+
430
+ ```typescript
431
+ // React 18 batches by default in event handlers and effects
432
+ // But for async operations, use flushSync if needed
433
+
434
+ import { flushSync } from 'react-dom';
435
+
436
+ // Normally batched (good)
437
+ function handleClick() {
438
+ setCount((c) => c + 1);
439
+ setFlag((f) => !f);
440
+ // React renders once
441
+ }
442
+
443
+ // Manual batching for legacy code or specific needs
444
+ function handleAsync() {
445
+ fetchData().then(() => {
446
+ // React 18: Already batched
447
+ setData(data);
448
+ setLoading(false);
449
+ });
450
+ }
451
+ ```
452
+
453
+ ### Avoid State Object Spreads in Loops
454
+
455
+ ```typescript
456
+ // BAD: Creates new object for each item
457
+ items.forEach((item) => {
458
+ setState((prev) => ({ ...prev, [item.id]: item })); // N state updates
459
+ });
460
+
461
+ // GOOD: Single update with all changes
462
+ setState((prev) => {
463
+ const updates: Record<string, Item> = {};
464
+ items.forEach((item) => {
465
+ updates[item.id] = item;
466
+ });
467
+ return { ...prev, ...updates }; // 1 state update
468
+ });
469
+ ```
470
+
471
+ ---
472
+
473
+ ## Bundle Size Optimization
474
+
475
+ ### Import Only What You Need
476
+
477
+ ```typescript
478
+ // BAD: Imports entire library
479
+ import _ from 'lodash';
480
+ _.debounce(fn, 300);
481
+
482
+ // GOOD: Import specific function
483
+ import debounce from 'lodash/debounce';
484
+ debounce(fn, 300);
485
+
486
+ // BEST: Use native or lighter alternative
487
+ function debounce(fn: Function, ms: number) {
488
+ let timeout: NodeJS.Timeout;
489
+ return (...args: unknown[]) => {
490
+ clearTimeout(timeout);
491
+ timeout = setTimeout(() => fn(...args), ms);
492
+ };
493
+ }
494
+ ```
495
+
496
+ ### Analyze Bundle
497
+
498
+ ```bash
499
+ # Vite bundle analyzer
500
+ pnpm add -D rollup-plugin-visualizer
501
+
502
+ # vite.config.ts
503
+ import { visualizer } from 'rollup-plugin-visualizer';
504
+
505
+ export default defineConfig({
506
+ plugins: [
507
+ react(),
508
+ visualizer({
509
+ filename: 'dist/stats.html',
510
+ open: true,
511
+ gzipSize: true,
512
+ }),
513
+ ],
514
+ });
515
+ ```
516
+
517
+ ### Tree Shaking
518
+
519
+ ```typescript
520
+ // Ensure library supports tree shaking (ESM)
521
+ // Check package.json for "module" or "exports" field
522
+
523
+ // Named exports tree-shake better than default
524
+ export { Button } from './Button';
525
+ export { Input } from './Input';
526
+ // vs
527
+ export default { Button, Input }; // Harder to tree-shake
528
+ ```
529
+
530
+ ---
531
+
532
+ ## Profiling
533
+
534
+ ### React DevTools Profiler
535
+
536
+ 1. Open React DevTools → Profiler tab
537
+ 2. Click Record
538
+ 3. Perform the slow action
539
+ 4. Click Stop
540
+ 5. Analyze flame graph and ranked chart
541
+
542
+ ### Performance API
543
+
544
+ ```typescript
545
+ // Measure component render time
546
+ function ExpensiveComponent() {
547
+ useEffect(() => {
548
+ performance.mark('expensive-start');
549
+
550
+ return () => {
551
+ performance.mark('expensive-end');
552
+ performance.measure('expensive-render', 'expensive-start', 'expensive-end');
553
+ const measure = performance.getEntriesByName('expensive-render')[0];
554
+ console.log(`Render took ${measure.duration}ms`);
555
+ };
556
+ }, []);
557
+
558
+ return <div>...</div>;
559
+ }
560
+ ```
561
+
562
+ ### Why Did You Render (Development)
563
+
564
+ ```typescript
565
+ // Install: pnpm add -D @welldone-software/why-did-you-render
566
+
567
+ // src/wdyr.ts
568
+ import React from 'react';
569
+
570
+ if (process.env.NODE_ENV === 'development') {
571
+ const whyDidYouRender = require('@welldone-software/why-did-you-render');
572
+ whyDidYouRender(React, {
573
+ trackAllPureComponents: true,
574
+ });
575
+ }
576
+
577
+ // Import before React in main.tsx
578
+ import './wdyr';
579
+ import React from 'react';
580
+ ```
581
+
582
+ ---
583
+
584
+ ## Core Web Vitals
585
+
586
+ | Metric | Target | Impact |
587
+ |--------|--------|--------|
588
+ | **LCP** (Largest Contentful Paint) | < 2.5s | Load performance |
589
+ | **FID** (First Input Delay) | < 100ms | Interactivity |
590
+ | **CLS** (Cumulative Layout Shift) | < 0.1 | Visual stability |
591
+ | **INP** (Interaction to Next Paint) | < 200ms | Responsiveness |
592
+
593
+ ### Avoid CLS
594
+
595
+ ```typescript
596
+ // Reserve space for images
597
+ <img src={url} alt={alt} width={400} height={300} />
598
+
599
+ // Or use aspect ratio
600
+ <div className="aspect-video">
601
+ <img src={url} alt={alt} className="h-full w-full object-cover" />
602
+ </div>
603
+
604
+ // Skeleton for async content
605
+ {isLoading ? (
606
+ <Skeleton className="h-40 w-full" />
607
+ ) : (
608
+ <Content data={data} />
609
+ )}
610
+ ```
611
+
612
+ ---
613
+
614
+ ## Anti-Patterns
615
+
616
+ | Anti-Pattern | Problem | Correct Approach |
617
+ |--------------|---------|------------------|
618
+ | Premature optimization | Wasted effort, complexity | Profile first, optimize bottlenecks |
619
+ | Memo everything | Memory overhead, complexity | Memo only expensive components |
620
+ | Inline objects in JSX | New reference every render | useMemo or extract to variable |
621
+ | State in parent for all | Unnecessary re-renders | Colocate state, use Zustand selectors |
622
+ | Giant components | Can't optimize parts | Split into smaller components |
623
+ | No loading states | Layout shift, bad UX | Use Suspense, skeletons |
624
+
625
+ ---
626
+
627
+ ## Quick Wins Checklist
628
+
629
+ - [ ] Route-level code splitting with React.lazy
630
+ - [ ] Images: loading="lazy", width/height attributes
631
+ - [ ] Virtualize lists > 100 items
632
+ - [ ] Debounce search/filter inputs (300ms)
633
+ - [ ] Use Zustand selectors (not full store)
634
+ - [ ] Production build with minification
635
+ - [ ] Bundle analyzer check for bloat
636
+ - [ ] Remove console.logs in production
637
+
638
+ ---
639
+
640
+ _Performance is a feature. Measure, optimize the bottlenecks, and ship fast._
@@ -6,22 +6,35 @@
6
6
 
7
7
  ## Core Capabilities
8
8
 
9
- [3-5 key capabilities of your React application]
9
+ Define 3-5 key capabilities of your React application:
10
10
 
11
- - [User interface capability]
12
- - [State management capability]
13
- - [Data handling capability]
11
+ - **Interactive UI**: Rich, responsive user interfaces with real-time feedback
12
+ - **Client-Side State**: Efficient state management for complex user workflows
13
+ - **Data Synchronization**: Seamless API integration with optimistic updates
14
+ - **Accessible Experience**: WCAG-compliant interfaces for all users
14
15
 
15
16
  ## Target Use Cases
16
17
 
17
- [Primary scenarios this React application addresses]
18
-
19
- 1. [User interaction scenario]
20
- 2. [Data visualization scenario]
18
+ 1. **Single Page Applications**: Complex client-side routing and state
19
+ 2. **Dashboard & Admin Panels**: Data-heavy interfaces with real-time updates
20
+ 3. **Forms & Workflows**: Multi-step processes with validation
21
+ 4. **Real-Time Features**: Live updates, notifications, collaborative editing
21
22
 
22
23
  ## Value Proposition
23
24
 
24
- [What makes this React application unique or valuable]
25
+ What makes this React application unique:
26
+
27
+ - **Performance**: Vite for instant HMR, optimized production builds
28
+ - **Type Safety**: Full TypeScript coverage prevents runtime errors
29
+ - **Developer Experience**: Modern tooling with fast feedback loops
30
+ - **Maintainability**: Component-based architecture with clear patterns
31
+
32
+ ## Success Metrics
33
+
34
+ - **Core Web Vitals**: LCP < 2.5s, FID < 100ms, CLS < 0.1
35
+ - **Test Coverage**: 80%+ for business logic
36
+ - **Bundle Size**: Initial load < 200KB gzipped
37
+ - **Accessibility**: Zero critical a11y violations
25
38
 
26
39
  ---
27
40
  _Focus on patterns and purpose, not exhaustive feature lists_