@brookmind/ai-toolkit 1.1.7 → 1.2.1

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 (149) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +42 -14
  3. package/dist/__tests__/constants.test.d.ts +2 -0
  4. package/dist/__tests__/constants.test.d.ts.map +1 -0
  5. package/dist/__tests__/constants.test.js +102 -0
  6. package/dist/__tests__/constants.test.js.map +1 -0
  7. package/dist/__tests__/index.test.d.ts +2 -0
  8. package/dist/__tests__/index.test.d.ts.map +1 -0
  9. package/dist/__tests__/index.test.js +114 -0
  10. package/dist/__tests__/index.test.js.map +1 -0
  11. package/dist/__tests__/integration/installer.test.d.ts +2 -0
  12. package/dist/__tests__/integration/installer.test.d.ts.map +1 -0
  13. package/dist/__tests__/integration/installer.test.js +425 -0
  14. package/dist/__tests__/integration/installer.test.js.map +1 -0
  15. package/dist/__tests__/services/installers.test.d.ts +2 -0
  16. package/dist/__tests__/services/installers.test.d.ts.map +1 -0
  17. package/dist/__tests__/services/installers.test.js +222 -0
  18. package/dist/__tests__/services/installers.test.js.map +1 -0
  19. package/dist/__tests__/services/opencode.test.d.ts +2 -0
  20. package/dist/__tests__/services/opencode.test.d.ts.map +1 -0
  21. package/dist/__tests__/services/opencode.test.js +120 -0
  22. package/dist/__tests__/services/opencode.test.js.map +1 -0
  23. package/dist/__tests__/ui/categorize.test.d.ts +2 -0
  24. package/dist/__tests__/ui/categorize.test.d.ts.map +1 -0
  25. package/dist/__tests__/ui/categorize.test.js +194 -0
  26. package/dist/__tests__/ui/categorize.test.js.map +1 -0
  27. package/dist/__tests__/ui/choices.test.d.ts +2 -0
  28. package/dist/__tests__/ui/choices.test.d.ts.map +1 -0
  29. package/dist/__tests__/ui/choices.test.js +180 -0
  30. package/dist/__tests__/ui/choices.test.js.map +1 -0
  31. package/dist/__tests__/ui/display.test.d.ts +2 -0
  32. package/dist/__tests__/ui/display.test.d.ts.map +1 -0
  33. package/dist/__tests__/ui/display.test.js +142 -0
  34. package/dist/__tests__/ui/display.test.js.map +1 -0
  35. package/dist/__tests__/utils/fs.test.d.ts +2 -0
  36. package/dist/__tests__/utils/fs.test.d.ts.map +1 -0
  37. package/dist/__tests__/utils/fs.test.js +142 -0
  38. package/dist/__tests__/utils/fs.test.js.map +1 -0
  39. package/dist/__tests__/utils/terminal.test.d.ts +2 -0
  40. package/dist/__tests__/utils/terminal.test.d.ts.map +1 -0
  41. package/dist/__tests__/utils/terminal.test.js +97 -0
  42. package/dist/__tests__/utils/terminal.test.js.map +1 -0
  43. package/dist/constants.d.ts +11 -0
  44. package/dist/constants.d.ts.map +1 -0
  45. package/dist/constants.js +40 -0
  46. package/dist/constants.js.map +1 -0
  47. package/dist/index.d.ts +2 -0
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +49 -332
  50. package/dist/index.js.map +1 -1
  51. package/dist/services/installers.d.ts +8 -0
  52. package/dist/services/installers.d.ts.map +1 -0
  53. package/dist/services/installers.js +79 -0
  54. package/dist/services/installers.js.map +1 -0
  55. package/dist/services/opencode.d.ts +3 -0
  56. package/dist/services/opencode.d.ts.map +1 -0
  57. package/dist/services/opencode.js +33 -0
  58. package/dist/services/opencode.js.map +1 -0
  59. package/dist/types.d.ts +10 -0
  60. package/dist/types.d.ts.map +1 -0
  61. package/dist/types.js +2 -0
  62. package/dist/types.js.map +1 -0
  63. package/dist/ui/categorize.d.ts +6 -0
  64. package/dist/ui/categorize.d.ts.map +1 -0
  65. package/dist/ui/categorize.js +69 -0
  66. package/dist/ui/categorize.js.map +1 -0
  67. package/dist/ui/choices.d.ts +6 -0
  68. package/dist/ui/choices.d.ts.map +1 -0
  69. package/dist/ui/choices.js +70 -0
  70. package/dist/ui/choices.js.map +1 -0
  71. package/dist/ui/display.d.ts +8 -0
  72. package/dist/ui/display.d.ts.map +1 -0
  73. package/dist/ui/display.js +86 -0
  74. package/dist/ui/display.js.map +1 -0
  75. package/dist/utils/fs.d.ts +5 -0
  76. package/dist/utils/fs.d.ts.map +1 -0
  77. package/dist/utils/fs.js +40 -0
  78. package/dist/utils/fs.js.map +1 -0
  79. package/dist/utils/terminal.d.ts +5 -0
  80. package/dist/utils/terminal.d.ts.map +1 -0
  81. package/dist/utils/terminal.js +18 -0
  82. package/dist/utils/terminal.js.map +1 -0
  83. package/package.json +29 -5
  84. package/agents/code-reviewer.md +0 -35
  85. package/agents/code-simplifier.md +0 -52
  86. package/commands/create-pr-description.md +0 -102
  87. package/commands/create-pr.md +0 -76
  88. package/commands/create-react-tests.md +0 -207
  89. package/mcps/context7/.mcp.json +0 -13
  90. package/mcps/expo-mcp/.mcp.json +0 -13
  91. package/mcps/figma-mcp/.mcp.json +0 -10
  92. package/skills/github-cli/SKILL.md +0 -125
  93. package/skills/pdf-processing-pro/FORMS.md +0 -610
  94. package/skills/pdf-processing-pro/OCR.md +0 -137
  95. package/skills/pdf-processing-pro/SKILL.md +0 -296
  96. package/skills/pdf-processing-pro/TABLES.md +0 -626
  97. package/skills/pdf-processing-pro/scripts/analyze_form.py +0 -307
  98. package/skills/react-best-practices/AGENTS.md +0 -915
  99. package/skills/react-best-practices/README.md +0 -127
  100. package/skills/react-best-practices/SKILL.md +0 -110
  101. package/skills/react-best-practices/metadata.json +0 -14
  102. package/skills/react-best-practices/rules/_sections.md +0 -41
  103. package/skills/react-best-practices/rules/_template.md +0 -28
  104. package/skills/react-best-practices/rules/advanced-event-handler-refs.md +0 -80
  105. package/skills/react-best-practices/rules/advanced-use-latest.md +0 -76
  106. package/skills/react-best-practices/rules/async-defer-await.md +0 -80
  107. package/skills/react-best-practices/rules/async-dependencies.md +0 -36
  108. package/skills/react-best-practices/rules/async-parallel.md +0 -28
  109. package/skills/react-best-practices/rules/async-suspense-boundaries.md +0 -100
  110. package/skills/react-best-practices/rules/bundle-barrel-imports.md +0 -42
  111. package/skills/react-best-practices/rules/bundle-conditional.md +0 -106
  112. package/skills/react-best-practices/rules/bundle-preload.md +0 -44
  113. package/skills/react-best-practices/rules/client-event-listeners.md +0 -131
  114. package/skills/react-best-practices/rules/client-swr-dedup.md +0 -133
  115. package/skills/react-best-practices/rules/js-batch-dom-css.md +0 -82
  116. package/skills/react-best-practices/rules/js-cache-function-results.md +0 -80
  117. package/skills/react-best-practices/rules/js-cache-property-access.md +0 -28
  118. package/skills/react-best-practices/rules/js-cache-storage.md +0 -70
  119. package/skills/react-best-practices/rules/js-combine-iterations.md +0 -32
  120. package/skills/react-best-practices/rules/js-early-exit.md +0 -50
  121. package/skills/react-best-practices/rules/js-hoist-regexp.md +0 -45
  122. package/skills/react-best-practices/rules/js-index-maps.md +0 -37
  123. package/skills/react-best-practices/rules/js-length-check-first.md +0 -49
  124. package/skills/react-best-practices/rules/js-min-max-loop.md +0 -82
  125. package/skills/react-best-practices/rules/js-set-map-lookups.md +0 -24
  126. package/skills/react-best-practices/rules/js-tosorted-immutable.md +0 -57
  127. package/skills/react-best-practices/rules/rendering-activity.md +0 -90
  128. package/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -47
  129. package/skills/react-best-practices/rules/rendering-conditional-render.md +0 -40
  130. package/skills/react-best-practices/rules/rendering-content-visibility.md +0 -38
  131. package/skills/react-best-practices/rules/rendering-hoist-jsx.md +0 -65
  132. package/skills/react-best-practices/rules/rendering-svg-precision.md +0 -28
  133. package/skills/react-best-practices/rules/rerender-defer-reads.md +0 -39
  134. package/skills/react-best-practices/rules/rerender-dependencies.md +0 -45
  135. package/skills/react-best-practices/rules/rerender-derived-state.md +0 -29
  136. package/skills/react-best-practices/rules/rerender-functional-setstate.md +0 -74
  137. package/skills/react-best-practices/rules/rerender-lazy-state-init.md +0 -58
  138. package/skills/react-best-practices/rules/rerender-memo.md +0 -85
  139. package/skills/react-best-practices/rules/rerender-transitions.md +0 -40
  140. package/skills/skill-creator/LICENSE.txt +0 -202
  141. package/skills/skill-creator/SKILL.md +0 -209
  142. package/skills/skill-creator/scripts/init_skill.py +0 -303
  143. package/skills/skill-creator/scripts/package_skill.py +0 -110
  144. package/skills/skill-creator/scripts/quick_validate.py +0 -65
  145. package/skills/spring-boot-development/EXAMPLES.md +0 -2346
  146. package/skills/spring-boot-development/README.md +0 -595
  147. package/skills/spring-boot-development/SKILL.md +0 -1519
  148. package/themes/README.md +0 -68
  149. package/themes/claude-vivid.json +0 -72
@@ -1,127 +0,0 @@
1
- # React Best Practices
2
-
3
- A structured repository for creating and maintaining React Best Practices optimized for agents and LLMs.
4
-
5
- ## Structure
6
-
7
- - `rules/` - Individual rule files (one per rule)
8
- - `_sections.md` - Section metadata (titles, impacts, descriptions)
9
- - `_template.md` - Template for creating new rules
10
- - `area-description.md` - Individual rule files
11
- - `src/` - Build scripts and utilities
12
- - `metadata.json` - Document metadata (version, organization, abstract)
13
- - **`AGENTS.md`** - Compiled output (generated)
14
- - **`test-cases.json`** - Test cases for LLM evaluation (generated)
15
-
16
- ## Getting Started
17
-
18
- 1. Install dependencies:
19
-
20
- ```bash
21
- pnpm install
22
- ```
23
-
24
- 2. Build AGENTS.md from rules:
25
-
26
- ```bash
27
- pnpm build
28
- ```
29
-
30
- 3. Validate rule files:
31
-
32
- ```bash
33
- pnpm validate
34
- ```
35
-
36
- 4. Extract test cases:
37
- ```bash
38
- pnpm extract-tests
39
- ```
40
-
41
- ## Creating a New Rule
42
-
43
- 1. Copy `rules/_template.md` to `rules/area-description.md`
44
- 2. Choose the appropriate area prefix:
45
- - `async-` for Eliminating Waterfalls (Section 1)
46
- - `bundle-` for Bundle Size Optimization (Section 2)
47
- - `server-` for Server-Side Performance (Section 3)
48
- - `client-` for Client-Side Data Fetching (Section 4)
49
- - `rerender-` for Re-render Optimization (Section 5)
50
- - `rendering-` for Rendering Performance (Section 6)
51
- - `js-` for JavaScript Performance (Section 7)
52
- - `advanced-` for Advanced Patterns (Section 8)
53
- 3. Fill in the frontmatter and content
54
- 4. Ensure you have clear examples with explanations
55
- 5. Run `pnpm build` to regenerate AGENTS.md and test-cases.json
56
-
57
- ## Rule File Structure
58
-
59
- Each rule file should follow this structure:
60
-
61
- ````markdown
62
- ---
63
- title: Rule Title Here
64
- impact: MEDIUM
65
- impactDescription: Optional description
66
- tags: tag1, tag2, tag3
67
- ---
68
-
69
- ## Rule Title Here
70
-
71
- Brief explanation of the rule and why it matters.
72
-
73
- **Incorrect (description of what's wrong):**
74
-
75
- ```typescript
76
- // Bad code example
77
- ```
78
- ````
79
-
80
- **Correct (description of what's right):**
81
-
82
- ```typescript
83
- // Good code example
84
- ```
85
-
86
- Optional explanatory text after examples.
87
-
88
- Reference: [Link](https://example.com)
89
-
90
- ## File Naming Convention
91
-
92
- - Files starting with `_` are special (excluded from build)
93
- - Rule files: `area-description.md` (e.g., `async-parallel.md`)
94
- - Section is automatically inferred from filename prefix
95
- - Rules are sorted alphabetically by title within each section
96
- - IDs (e.g., 1.1, 1.2) are auto-generated during build
97
-
98
- ## Impact Levels
99
-
100
- - `CRITICAL` - Highest priority, major performance gains
101
- - `HIGH` - Significant performance improvements
102
- - `MEDIUM-HIGH` - Moderate-high gains
103
- - `MEDIUM` - Moderate performance improvements
104
- - `LOW-MEDIUM` - Low-medium gains
105
- - `LOW` - Incremental improvements
106
-
107
- ## Scripts
108
-
109
- - `pnpm build` - Compile rules into AGENTS.md
110
- - `pnpm validate` - Validate all rule files
111
- - `pnpm extract-tests` - Extract test cases for LLM evaluation
112
- - `pnpm dev` - Build and validate
113
-
114
- ## Contributing
115
-
116
- When adding or modifying rules:
117
-
118
- 1. Use the correct filename prefix for your section
119
- 2. Follow the `_template.md` structure
120
- 3. Include clear bad/good examples with explanations
121
- 4. Add appropriate tags
122
- 5. Run `pnpm build` to regenerate AGENTS.md and test-cases.json
123
- 6. Rules are automatically sorted by title - no need to manage numbers!
124
-
125
- ## Acknowledgments
126
-
127
- Originally created by [@shuding](https://x.com/shuding) at [Vercel](https://vercel.com).
@@ -1,110 +0,0 @@
1
- ---
2
- name: vercel-react-best-practices
3
- description: React performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React code to ensure optimal performance patterns. Triggers on tasks involving React components, data fetching, bundle optimization, or performance improvements.
4
- ---
5
-
6
- # Vercel React Best Practices
7
-
8
- Comprehensive performance optimization guide for React applications, maintained by Vercel. Contains 35+ rules across 7 categories, prioritized by impact to guide automated refactoring and code generation.
9
-
10
- ## When to Apply
11
-
12
- Reference these guidelines when:
13
-
14
- - Writing new React components
15
- - Implementing data fetching (client-side)
16
- - Reviewing code for performance issues
17
- - Refactoring existing React code
18
- - Optimizing bundle size or load times
19
-
20
- ## Rule Categories by Priority
21
-
22
- | Priority | Category | Impact | Prefix |
23
- | -------- | ------------------------- | ----------- | ------------ |
24
- | 1 | Eliminating Waterfalls | CRITICAL | `async-` |
25
- | 2 | Bundle Size Optimization | CRITICAL | `bundle-` |
26
- | 3 | Client-Side Data Fetching | MEDIUM-HIGH | `client-` |
27
- | 4 | Re-render Optimization | MEDIUM | `rerender-` |
28
- | 5 | Rendering Performance | MEDIUM | `rendering-` |
29
- | 6 | JavaScript Performance | LOW-MEDIUM | `js-` |
30
- | 7 | Advanced Patterns | LOW | `advanced-` |
31
-
32
- ## Quick Reference
33
-
34
- ### 1. Eliminating Waterfalls (CRITICAL)
35
-
36
- - `async-defer-await` - Move await into branches where actually used
37
- - `async-parallel` - Use Promise.all() for independent operations
38
- - `async-dependencies` - Use better-all for partial dependencies
39
- - `async-suspense-boundaries` - Use Suspense to stream content
40
-
41
- ### 2. Bundle Size Optimization (CRITICAL)
42
-
43
- - `bundle-barrel-imports` - Import directly, avoid barrel files
44
- - `bundle-conditional` - Load modules only when feature is activated
45
- - `bundle-preload` - Preload on hover/focus for perceived speed
46
-
47
- ### 3. Client-Side Data Fetching (MEDIUM-HIGH)
48
-
49
- - `client-swr-dedup` - Use React Query for automatic request deduplication
50
- - `client-event-listeners` - Deduplicate global event listeners with useSyncExternalStore
51
-
52
- ### 4. Re-render Optimization (MEDIUM)
53
-
54
- - `rerender-defer-reads` - Don't subscribe to state only used in callbacks
55
- - `rerender-memo` - Extract expensive work into memoized components
56
- - `rerender-dependencies` - Use primitive dependencies in effects
57
- - `rerender-derived-state` - Subscribe to derived booleans, not raw values
58
- - `rerender-functional-setstate` - Use functional setState for stable callbacks
59
- - `rerender-lazy-state-init` - Pass function to useState for expensive values
60
- - `rerender-transitions` - Use startTransition for non-urgent updates
61
-
62
- ### 4. Rendering Performance (MEDIUM)
63
-
64
- - `rendering-animate-svg-wrapper` - Animate div wrapper, not SVG element
65
- - `rendering-content-visibility` - Use content-visibility for long lists
66
- - `rendering-hoist-jsx` - Extract static JSX outside components
67
- - `rendering-svg-precision` - Reduce SVG coordinate precision
68
- - `rendering-activity` - Use Activity component for show/hide
69
- - `rendering-conditional-render` - Use ternary, not && for conditionals
70
-
71
- ### 5. JavaScript Performance (LOW-MEDIUM)
72
-
73
- - `js-batch-dom-css` - Group CSS changes via classes or cssText
74
- - `js-index-maps` - Build Map for repeated lookups
75
- - `js-cache-property-access` - Cache object properties in loops
76
- - `js-cache-function-results` - Cache function results in module-level Map
77
- - `js-cache-storage` - Cache localStorage/sessionStorage reads
78
- - `js-combine-iterations` - Combine multiple filter/map into one loop
79
- - `js-length-check-first` - Check array length before expensive comparison
80
- - `js-early-exit` - Return early from functions
81
- - `js-hoist-regexp` - Hoist RegExp creation outside loops
82
- - `js-min-max-loop` - Use loop for min/max instead of sort
83
- - `js-set-map-lookups` - Use Set/Map for O(1) lookups
84
- - `js-tosorted-immutable` - Use toSorted() for immutability
85
-
86
- ### 6. Advanced Patterns (LOW)
87
-
88
- - `advanced-event-handler-refs` - Stable event handler references with useEffectEvent
89
- - `advanced-use-latest` - Stable callbacks with useEffectEvent (React 19)
90
-
91
- ## How to Use
92
-
93
- Read individual rule files for detailed explanations and code examples:
94
-
95
- ```
96
- rules/async-parallel.md
97
- rules/bundle-barrel-imports.md
98
- rules/_sections.md
99
- ```
100
-
101
- Each rule file contains:
102
-
103
- - Brief explanation of why it matters
104
- - Incorrect code example with explanation
105
- - Correct code example with explanation
106
- - Additional context and references
107
-
108
- ## Full Compiled Document
109
-
110
- For the complete guide with all rules expanded: `AGENTS.md`
@@ -1,14 +0,0 @@
1
- {
2
- "version": "0.1.0",
3
- "organization": "Vercel Engineering",
4
- "date": "January 2026",
5
- "abstract": "Comprehensive performance optimization guide for React applications, designed for AI agents and LLMs. Contains 40+ rules across 8 categories, prioritized by impact from critical (eliminating waterfalls, reducing bundle size) to incremental (advanced patterns). Each rule includes detailed explanations, real-world examples comparing incorrect vs. correct implementations, and specific impact metrics to guide automated refactoring and code generation.",
6
- "references": [
7
- "https://react.dev",
8
- "https://swr.vercel.app",
9
- "https://github.com/shuding/better-all",
10
- "https://github.com/isaacs/node-lru-cache",
11
- "https://vercel.com/blog/how-we-optimized-package-imports-in-next-js",
12
- "https://vercel.com/blog/how-we-made-the-vercel-dashboard-twice-as-fast"
13
- ]
14
- }
@@ -1,41 +0,0 @@
1
- # Sections
2
-
3
- This file defines all sections, their ordering, impact levels, and descriptions.
4
- The section ID (in parentheses) is the filename prefix used to group rules.
5
-
6
- ---
7
-
8
- ## 1. Eliminating Waterfalls (async)
9
-
10
- **Impact:** CRITICAL
11
- **Description:** Waterfalls are the #1 performance killer. Each sequential await adds full network latency. Eliminating them yields the largest gains.
12
-
13
- ## 2. Bundle Size Optimization (bundle)
14
-
15
- **Impact:** CRITICAL
16
- **Description:** Reducing initial bundle size improves Time to Interactive and Largest Contentful Paint.
17
-
18
- ## 3. Client-Side Data Fetching (client)
19
-
20
- **Impact:** MEDIUM-HIGH
21
- **Description:** Automatic deduplication and efficient data fetching patterns reduce redundant network requests.
22
-
23
- ## 4. Re-render Optimization (rerender)
24
-
25
- **Impact:** MEDIUM
26
- **Description:** Reducing unnecessary re-renders minimizes wasted computation and improves UI responsiveness.
27
-
28
- ## 5. Rendering Performance (rendering)
29
-
30
- **Impact:** MEDIUM
31
- **Description:** Optimizing the rendering process reduces the work the browser needs to do.
32
-
33
- ## 6. JavaScript Performance (js)
34
-
35
- **Impact:** LOW-MEDIUM
36
- **Description:** Micro-optimizations for hot paths can add up to meaningful improvements.
37
-
38
- ## 7. Advanced Patterns (advanced)
39
-
40
- **Impact:** LOW
41
- **Description:** Advanced patterns for specific cases that require careful implementation.
@@ -1,28 +0,0 @@
1
- ---
2
- title: Rule Title Here
3
- impact: MEDIUM
4
- impactDescription: Optional description of impact (e.g., "20-50% improvement")
5
- tags: tag1, tag2
6
- ---
7
-
8
- ## Rule Title Here
9
-
10
- **Impact: MEDIUM (optional impact description)**
11
-
12
- Brief explanation of the rule and why it matters. This should be clear and concise, explaining the performance implications.
13
-
14
- **Incorrect (description of what's wrong):**
15
-
16
- ```typescript
17
- // Bad code example here
18
- const bad = example()
19
- ```
20
-
21
- **Correct (description of what's right):**
22
-
23
- ```typescript
24
- // Good code example here
25
- const good = example()
26
- ```
27
-
28
- Reference: [Link to documentation or resource](https://example.com)
@@ -1,80 +0,0 @@
1
- ---
2
- title: Stable Event Handler References
3
- impact: MEDIUM
4
- impactDescription: stable subscriptions without re-subscribing
5
- tags: advanced, hooks, useEffectEvent, refs, event-handlers, react-19
6
- ---
7
-
8
- ## Stable Event Handler References
9
-
10
- Use `useEffectEvent` (React 19) for stable event handler references in effects. This prevents re-subscribing to events when callbacks change.
11
-
12
- **React 19 with useEffectEvent (Recommended):**
13
-
14
- ```tsx
15
- import { useEffectEvent } from "react";
16
-
17
- function useWindowEvent(event: string, handler: () => void) {
18
- // useEffectEvent creates a stable reference that always calls latest handler
19
- const onEvent = useEffectEvent(handler);
20
-
21
- useEffect(() => {
22
- window.addEventListener(event, onEvent);
23
- return () => window.removeEventListener(event, onEvent);
24
- }, [event]); // No need to include onEvent - it's always stable
25
- }
26
-
27
- // Usage
28
- function Component({ onResize }: { onResize: () => void }) {
29
- useWindowEvent("resize", onResize);
30
- // Effect won't re-run when onResize changes!
31
- }
32
- ```
33
-
34
- **Why useEffectEvent?**
35
-
36
- - Creates a stable function reference
37
- - Always calls the latest version of the callback
38
- - No stale closure issues
39
- - Clean, official React API
40
-
41
- **Incorrect (re-subscribes on every callback change):**
42
-
43
- ```tsx
44
- function useWindowEvent(event: string, handler: () => void) {
45
- useEffect(() => {
46
- window.addEventListener(event, handler);
47
- return () => window.removeEventListener(event, handler);
48
- }, [event, handler]); // Re-subscribes when handler changes!
49
- }
50
- ```
51
-
52
- **Legacy fallback with refs (pre-React 19):**
53
-
54
- If you're not on React 19, use the ref pattern:
55
-
56
- ```tsx
57
- function useWindowEvent(event: string, handler: () => void) {
58
- const handlerRef = useRef(handler);
59
-
60
- // Keep ref updated with latest handler
61
- useEffect(() => {
62
- handlerRef.current = handler;
63
- }, [handler]);
64
-
65
- useEffect(() => {
66
- const listener = (e: Event) => handlerRef.current();
67
- window.addEventListener(event, listener);
68
- return () => window.removeEventListener(event, listener);
69
- }, [event]);
70
- }
71
- ```
72
-
73
- **Common use cases:**
74
-
75
- - Window event listeners (resize, scroll, keydown)
76
- - WebSocket message handlers
77
- - Interval/timeout callbacks
78
- - Any subscription that shouldn't re-subscribe on callback change
79
-
80
- Reference: [useEffectEvent RFC](https://react.dev/learn/separating-events-from-effects#declaring-an-effect-event)
@@ -1,76 +0,0 @@
1
- ---
2
- title: Stable Event Callbacks with useEffectEvent
3
- impact: MEDIUM
4
- impactDescription: prevents effect re-runs and stale closures
5
- tags: advanced, hooks, useEffectEvent, react-19, callbacks
6
- ---
7
-
8
- ## Stable Event Callbacks with useEffectEvent
9
-
10
- Use `useEffectEvent` (React 19) to access latest values in effect callbacks without adding them to dependency arrays. This prevents effect re-runs while avoiding stale closures.
11
-
12
- **Incorrect (effect re-runs on every callback change):**
13
-
14
- ```tsx
15
- function SearchInput({ onSearch }: { onSearch: (q: string) => void }) {
16
- const [query, setQuery] = useState("");
17
-
18
- useEffect(() => {
19
- const timeout = setTimeout(() => onSearch(query), 300);
20
- return () => clearTimeout(timeout);
21
- }, [query, onSearch]); // onSearch causes unnecessary re-runs
22
- }
23
- ```
24
-
25
- **Correct (React 19 - useEffectEvent):**
26
-
27
- ```tsx
28
- import { useEffectEvent } from "react";
29
-
30
- function SearchInput({ onSearch }: { onSearch: (q: string) => void }) {
31
- const [query, setQuery] = useState("");
32
-
33
- // useEffectEvent creates a stable reference that always calls the latest onSearch
34
- const onSearchEvent = useEffectEvent((q: string) => {
35
- onSearch(q);
36
- });
37
-
38
- useEffect(() => {
39
- const timeout = setTimeout(() => onSearchEvent(query), 300);
40
- return () => clearTimeout(timeout);
41
- }, [query]); // No need to include onSearchEvent - it's always stable
42
- }
43
- ```
44
-
45
- **Why useEffectEvent?**
46
-
47
- - Always calls the latest version of the callback
48
- - Stable reference - never triggers effect re-runs
49
- - No stale closure bugs
50
- - Official React 19 solution (replaces custom `useLatest` hooks)
51
-
52
- **Legacy fallback (pre-React 19):**
53
-
54
- If you're not on React 19 yet, use a ref-based pattern:
55
-
56
- ```tsx
57
- function useLatest<T>(value: T) {
58
- const ref = useRef(value);
59
- useEffect(() => {
60
- ref.current = value;
61
- }, [value]);
62
- return ref;
63
- }
64
-
65
- function SearchInput({ onSearch }: { onSearch: (q: string) => void }) {
66
- const [query, setQuery] = useState("");
67
- const onSearchRef = useLatest(onSearch);
68
-
69
- useEffect(() => {
70
- const timeout = setTimeout(() => onSearchRef.current(query), 300);
71
- return () => clearTimeout(timeout);
72
- }, [query]);
73
- }
74
- ```
75
-
76
- **Note:** Prefer `useEffectEvent` when available - it's the official React solution.
@@ -1,80 +0,0 @@
1
- ---
2
- title: Defer Await Until Needed
3
- impact: HIGH
4
- impactDescription: avoids blocking unused code paths
5
- tags: async, await, conditional, optimization
6
- ---
7
-
8
- ## Defer Await Until Needed
9
-
10
- Move `await` operations into the branches where they're actually used to avoid blocking code paths that don't need them.
11
-
12
- **Incorrect (blocks both branches):**
13
-
14
- ```typescript
15
- async function handleRequest(userId: string, skipProcessing: boolean) {
16
- const userData = await fetchUserData(userId)
17
-
18
- if (skipProcessing) {
19
- // Returns immediately but still waited for userData
20
- return { skipped: true }
21
- }
22
-
23
- // Only this branch uses userData
24
- return processUserData(userData)
25
- }
26
- ```
27
-
28
- **Correct (only blocks when needed):**
29
-
30
- ```typescript
31
- async function handleRequest(userId: string, skipProcessing: boolean) {
32
- if (skipProcessing) {
33
- // Returns immediately without waiting
34
- return { skipped: true }
35
- }
36
-
37
- // Fetch only when needed
38
- const userData = await fetchUserData(userId)
39
- return processUserData(userData)
40
- }
41
- ```
42
-
43
- **Another example (early return optimization):**
44
-
45
- ```typescript
46
- // Incorrect: always fetches permissions
47
- async function updateResource(resourceId: string, userId: string) {
48
- const permissions = await fetchPermissions(userId)
49
- const resource = await getResource(resourceId)
50
-
51
- if (!resource) {
52
- return { error: 'Not found' }
53
- }
54
-
55
- if (!permissions.canEdit) {
56
- return { error: 'Forbidden' }
57
- }
58
-
59
- return await updateResourceData(resource, permissions)
60
- }
61
-
62
- // Correct: fetches only when needed
63
- async function updateResource(resourceId: string, userId: string) {
64
- const resource = await getResource(resourceId)
65
-
66
- if (!resource) {
67
- return { error: 'Not found' }
68
- }
69
-
70
- const permissions = await fetchPermissions(userId)
71
-
72
- if (!permissions.canEdit) {
73
- return { error: 'Forbidden' }
74
- }
75
-
76
- return await updateResourceData(resource, permissions)
77
- }
78
- ```
79
-
80
- This optimization is especially valuable when the skipped branch is frequently taken, or when the deferred operation is expensive.
@@ -1,36 +0,0 @@
1
- ---
2
- title: Dependency-Based Parallelization
3
- impact: CRITICAL
4
- impactDescription: 2-10× improvement
5
- tags: async, parallelization, dependencies, better-all
6
- ---
7
-
8
- ## Dependency-Based Parallelization
9
-
10
- For operations with partial dependencies, use `better-all` to maximize parallelism. It automatically starts each task at the earliest possible moment.
11
-
12
- **Incorrect (profile waits for config unnecessarily):**
13
-
14
- ```typescript
15
- const [user, config] = await Promise.all([
16
- fetchUser(),
17
- fetchConfig()
18
- ])
19
- const profile = await fetchProfile(user.id)
20
- ```
21
-
22
- **Correct (config and profile run in parallel):**
23
-
24
- ```typescript
25
- import { all } from 'better-all'
26
-
27
- const { user, config, profile } = await all({
28
- async user() { return fetchUser() },
29
- async config() { return fetchConfig() },
30
- async profile() {
31
- return fetchProfile((await this.$.user).id)
32
- }
33
- })
34
- ```
35
-
36
- Reference: [https://github.com/shuding/better-all](https://github.com/shuding/better-all)
@@ -1,28 +0,0 @@
1
- ---
2
- title: Promise.all() for Independent Operations
3
- impact: CRITICAL
4
- impactDescription: 2-10× improvement
5
- tags: async, parallelization, promises, waterfalls
6
- ---
7
-
8
- ## Promise.all() for Independent Operations
9
-
10
- When async operations have no interdependencies, execute them concurrently using `Promise.all()`.
11
-
12
- **Incorrect (sequential execution, 3 round trips):**
13
-
14
- ```typescript
15
- const user = await fetchUser()
16
- const posts = await fetchPosts()
17
- const comments = await fetchComments()
18
- ```
19
-
20
- **Correct (parallel execution, 1 round trip):**
21
-
22
- ```typescript
23
- const [user, posts, comments] = await Promise.all([
24
- fetchUser(),
25
- fetchPosts(),
26
- fetchComments()
27
- ])
28
- ```