@mrtrinhvn/ag-kit 1.0.11 → 1.1.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 (219) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -0
  3. package/bin/cli.js +62 -0
  4. package/package.json +7 -1
  5. package/template/.agent/rules/GEMINI.md +1 -1
  6. package/template/.agent/skills/regent-orchestrator/SKILL.md +31 -0
  7. package/template/.agent/skills/telegram-bridge/SKILL.md +30 -0
  8. package/.agent/.shared/ui-ux-pro-max/data/charts.csv +0 -26
  9. package/.agent/.shared/ui-ux-pro-max/data/colors.csv +0 -97
  10. package/.agent/.shared/ui-ux-pro-max/data/icons.csv +0 -101
  11. package/.agent/.shared/ui-ux-pro-max/data/landing.csv +0 -31
  12. package/.agent/.shared/ui-ux-pro-max/data/products.csv +0 -97
  13. package/.agent/.shared/ui-ux-pro-max/data/prompts.csv +0 -24
  14. package/.agent/.shared/ui-ux-pro-max/data/react-performance.csv +0 -45
  15. package/.agent/.shared/ui-ux-pro-max/data/stacks/flutter.csv +0 -53
  16. package/.agent/.shared/ui-ux-pro-max/data/stacks/html-tailwind.csv +0 -56
  17. package/.agent/.shared/ui-ux-pro-max/data/stacks/jetpack-compose.csv +0 -53
  18. package/.agent/.shared/ui-ux-pro-max/data/stacks/nextjs.csv +0 -53
  19. package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxt-ui.csv +0 -51
  20. package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxtjs.csv +0 -59
  21. package/.agent/.shared/ui-ux-pro-max/data/stacks/react-native.csv +0 -52
  22. package/.agent/.shared/ui-ux-pro-max/data/stacks/react.csv +0 -54
  23. package/.agent/.shared/ui-ux-pro-max/data/stacks/shadcn.csv +0 -61
  24. package/.agent/.shared/ui-ux-pro-max/data/stacks/svelte.csv +0 -54
  25. package/.agent/.shared/ui-ux-pro-max/data/stacks/swiftui.csv +0 -51
  26. package/.agent/.shared/ui-ux-pro-max/data/stacks/vue.csv +0 -50
  27. package/.agent/.shared/ui-ux-pro-max/data/styles.csv +0 -59
  28. package/.agent/.shared/ui-ux-pro-max/data/typography.csv +0 -58
  29. package/.agent/.shared/ui-ux-pro-max/data/ui-reasoning.csv +0 -101
  30. package/.agent/.shared/ui-ux-pro-max/data/ux-guidelines.csv +0 -100
  31. package/.agent/.shared/ui-ux-pro-max/data/web-interface.csv +0 -31
  32. package/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/core.cpython-313.pyc +0 -0
  33. package/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-313.pyc +0 -0
  34. package/.agent/.shared/ui-ux-pro-max/scripts/core.py +0 -258
  35. package/.agent/.shared/ui-ux-pro-max/scripts/design_system.py +0 -1067
  36. package/.agent/.shared/ui-ux-pro-max/scripts/search.py +0 -106
  37. package/.agent/ARCHITECTURE.md +0 -288
  38. package/.agent/agents/backend-specialist.md +0 -263
  39. package/.agent/agents/code-archaeologist.md +0 -106
  40. package/.agent/agents/database-architect.md +0 -226
  41. package/.agent/agents/debugger.md +0 -225
  42. package/.agent/agents/devops-engineer.md +0 -242
  43. package/.agent/agents/documentation-writer.md +0 -104
  44. package/.agent/agents/explorer-agent.md +0 -73
  45. package/.agent/agents/frontend-specialist.md +0 -556
  46. package/.agent/agents/game-developer.md +0 -162
  47. package/.agent/agents/mobile-developer.md +0 -377
  48. package/.agent/agents/orchestrator.md +0 -416
  49. package/.agent/agents/penetration-tester.md +0 -188
  50. package/.agent/agents/performance-optimizer.md +0 -187
  51. package/.agent/agents/product-manager.md +0 -112
  52. package/.agent/agents/product-owner.md +0 -95
  53. package/.agent/agents/project-planner.md +0 -406
  54. package/.agent/agents/qa-automation-engineer.md +0 -103
  55. package/.agent/agents/quant-architect.md +0 -31
  56. package/.agent/agents/security-auditor.md +0 -170
  57. package/.agent/agents/seo-specialist.md +0 -111
  58. package/.agent/agents/test-engineer.md +0 -158
  59. package/.agent/mcp_config.json +0 -24
  60. package/.agent/rules/GEMINI.md +0 -280
  61. package/.agent/scripts/auto_preview.py +0 -148
  62. package/.agent/scripts/checklist.py +0 -217
  63. package/.agent/scripts/session_manager.py +0 -120
  64. package/.agent/scripts/verify_all.py +0 -327
  65. package/.agent/skills/api-patterns/SKILL.md +0 -81
  66. package/.agent/skills/api-patterns/api-style.md +0 -42
  67. package/.agent/skills/api-patterns/auth.md +0 -24
  68. package/.agent/skills/api-patterns/documentation.md +0 -26
  69. package/.agent/skills/api-patterns/graphql.md +0 -41
  70. package/.agent/skills/api-patterns/rate-limiting.md +0 -31
  71. package/.agent/skills/api-patterns/response.md +0 -37
  72. package/.agent/skills/api-patterns/rest.md +0 -40
  73. package/.agent/skills/api-patterns/scripts/api_validator.py +0 -211
  74. package/.agent/skills/api-patterns/security-testing.md +0 -122
  75. package/.agent/skills/api-patterns/trpc.md +0 -41
  76. package/.agent/skills/api-patterns/versioning.md +0 -22
  77. package/.agent/skills/app-builder/SKILL.md +0 -75
  78. package/.agent/skills/app-builder/agent-coordination.md +0 -71
  79. package/.agent/skills/app-builder/feature-building.md +0 -53
  80. package/.agent/skills/app-builder/project-detection.md +0 -34
  81. package/.agent/skills/app-builder/scaffolding.md +0 -118
  82. package/.agent/skills/app-builder/tech-stack.md +0 -40
  83. package/.agent/skills/app-builder/templates/SKILL.md +0 -39
  84. package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +0 -76
  85. package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +0 -92
  86. package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +0 -88
  87. package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +0 -88
  88. package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +0 -83
  89. package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +0 -90
  90. package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +0 -90
  91. package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +0 -82
  92. package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +0 -100
  93. package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +0 -106
  94. package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +0 -101
  95. package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +0 -83
  96. package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +0 -93
  97. package/.agent/skills/architecture/SKILL.md +0 -55
  98. package/.agent/skills/architecture/context-discovery.md +0 -43
  99. package/.agent/skills/architecture/examples.md +0 -94
  100. package/.agent/skills/architecture/pattern-selection.md +0 -68
  101. package/.agent/skills/architecture/patterns-reference.md +0 -50
  102. package/.agent/skills/architecture/trade-off-analysis.md +0 -77
  103. package/.agent/skills/bash-linux/SKILL.md +0 -199
  104. package/.agent/skills/behavioral-modes/SKILL.md +0 -242
  105. package/.agent/skills/brainstorming/SKILL.md +0 -168
  106. package/.agent/skills/brainstorming/dynamic-questioning.md +0 -350
  107. package/.agent/skills/business-ops/SKILL.md +0 -26
  108. package/.agent/skills/clean-code/SKILL.md +0 -202
  109. package/.agent/skills/cli-generator/SKILL.md +0 -48
  110. package/.agent/skills/code-review-checklist/SKILL.md +0 -109
  111. package/.agent/skills/cognitive-session/SKILL.md +0 -28
  112. package/.agent/skills/data-science/SKILL.md +0 -28
  113. package/.agent/skills/database-design/SKILL.md +0 -52
  114. package/.agent/skills/database-design/database-selection.md +0 -43
  115. package/.agent/skills/database-design/indexing.md +0 -39
  116. package/.agent/skills/database-design/migrations.md +0 -48
  117. package/.agent/skills/database-design/optimization.md +0 -36
  118. package/.agent/skills/database-design/orm-selection.md +0 -30
  119. package/.agent/skills/database-design/schema-design.md +0 -56
  120. package/.agent/skills/database-design/scripts/schema_validator.py +0 -172
  121. package/.agent/skills/deployment-procedures/SKILL.md +0 -241
  122. package/.agent/skills/doc.md +0 -177
  123. package/.agent/skills/documentation-templates/SKILL.md +0 -194
  124. package/.agent/skills/frontend-design/SKILL.md +0 -418
  125. package/.agent/skills/frontend-design/animation-guide.md +0 -331
  126. package/.agent/skills/frontend-design/color-system.md +0 -311
  127. package/.agent/skills/frontend-design/decision-trees.md +0 -418
  128. package/.agent/skills/frontend-design/motion-graphics.md +0 -306
  129. package/.agent/skills/frontend-design/scripts/accessibility_checker.py +0 -183
  130. package/.agent/skills/frontend-design/scripts/ux_audit.py +0 -722
  131. package/.agent/skills/frontend-design/typography-system.md +0 -345
  132. package/.agent/skills/frontend-design/ux-psychology.md +0 -541
  133. package/.agent/skills/frontend-design/visual-effects.md +0 -383
  134. package/.agent/skills/game-development/2d-games/SKILL.md +0 -119
  135. package/.agent/skills/game-development/3d-games/SKILL.md +0 -135
  136. package/.agent/skills/game-development/SKILL.md +0 -167
  137. package/.agent/skills/game-development/game-art/SKILL.md +0 -185
  138. package/.agent/skills/game-development/game-audio/SKILL.md +0 -190
  139. package/.agent/skills/game-development/game-design/SKILL.md +0 -129
  140. package/.agent/skills/game-development/mobile-games/SKILL.md +0 -108
  141. package/.agent/skills/game-development/multiplayer/SKILL.md +0 -132
  142. package/.agent/skills/game-development/pc-games/SKILL.md +0 -144
  143. package/.agent/skills/game-development/vr-ar/SKILL.md +0 -123
  144. package/.agent/skills/game-development/web-games/SKILL.md +0 -150
  145. package/.agent/skills/geo-fundamentals/SKILL.md +0 -156
  146. package/.agent/skills/geo-fundamentals/scripts/geo_checker.py +0 -289
  147. package/.agent/skills/i18n-localization/SKILL.md +0 -154
  148. package/.agent/skills/i18n-localization/scripts/i18n_checker.py +0 -241
  149. package/.agent/skills/intelligent-routing/SKILL.md +0 -335
  150. package/.agent/skills/knowledge-management/SKILL.md +0 -66
  151. package/.agent/skills/lint-and-validate/SKILL.md +0 -45
  152. package/.agent/skills/lint-and-validate/scripts/lint_runner.py +0 -172
  153. package/.agent/skills/lint-and-validate/scripts/type_coverage.py +0 -173
  154. package/.agent/skills/llm-routing-quirks/SKILL.md +0 -41
  155. package/.agent/skills/mcp-builder/SKILL.md +0 -176
  156. package/.agent/skills/memory-architecture/SKILL.md +0 -107
  157. package/.agent/skills/mini-antigravity-injection/SKILL.md +0 -66
  158. package/.agent/skills/mobile-design/SKILL.md +0 -394
  159. package/.agent/skills/mobile-design/decision-trees.md +0 -516
  160. package/.agent/skills/mobile-design/mobile-backend.md +0 -491
  161. package/.agent/skills/mobile-design/mobile-color-system.md +0 -420
  162. package/.agent/skills/mobile-design/mobile-debugging.md +0 -122
  163. package/.agent/skills/mobile-design/mobile-design-thinking.md +0 -357
  164. package/.agent/skills/mobile-design/mobile-navigation.md +0 -458
  165. package/.agent/skills/mobile-design/mobile-performance.md +0 -767
  166. package/.agent/skills/mobile-design/mobile-testing.md +0 -356
  167. package/.agent/skills/mobile-design/mobile-typography.md +0 -433
  168. package/.agent/skills/mobile-design/platform-android.md +0 -666
  169. package/.agent/skills/mobile-design/platform-ios.md +0 -561
  170. package/.agent/skills/mobile-design/scripts/mobile_audit.py +0 -670
  171. package/.agent/skills/mobile-design/touch-psychology.md +0 -537
  172. package/.agent/skills/nextjs-react-expert/1-async-eliminating-waterfalls.md +0 -312
  173. package/.agent/skills/nextjs-react-expert/2-bundle-bundle-size-optimization.md +0 -240
  174. package/.agent/skills/nextjs-react-expert/3-server-server-side-performance.md +0 -490
  175. package/.agent/skills/nextjs-react-expert/4-client-client-side-data-fetching.md +0 -264
  176. package/.agent/skills/nextjs-react-expert/5-rerender-re-render-optimization.md +0 -581
  177. package/.agent/skills/nextjs-react-expert/6-rendering-rendering-performance.md +0 -432
  178. package/.agent/skills/nextjs-react-expert/7-js-javascript-performance.md +0 -684
  179. package/.agent/skills/nextjs-react-expert/8-advanced-advanced-patterns.md +0 -150
  180. package/.agent/skills/nextjs-react-expert/9-cache-components.md +0 -103
  181. package/.agent/skills/nextjs-react-expert/SKILL.md +0 -267
  182. package/.agent/skills/nextjs-react-expert/scripts/convert_rules.py +0 -222
  183. package/.agent/skills/nextjs-react-expert/scripts/react_performance_checker.py +0 -252
  184. package/.agent/skills/nodejs-best-practices/SKILL.md +0 -333
  185. package/.agent/skills/parallel-agents/SKILL.md +0 -175
  186. package/.agent/skills/performance-profiling/SKILL.md +0 -143
  187. package/.agent/skills/performance-profiling/scripts/lighthouse_audit.py +0 -76
  188. package/.agent/skills/plan-writing/SKILL.md +0 -153
  189. package/.agent/skills/powershell-windows/SKILL.md +0 -167
  190. package/.agent/skills/product-management/SKILL.md +0 -30
  191. package/.agent/skills/python-patterns/SKILL.md +0 -441
  192. package/.agent/skills/red-team-tactics/SKILL.md +0 -199
  193. package/.agent/skills/rust-pro/SKILL.md +0 -176
  194. package/.agent/skills/seo-fundamentals/SKILL.md +0 -129
  195. package/.agent/skills/seo-fundamentals/scripts/seo_checker.py +0 -219
  196. package/.agent/skills/server-management/SKILL.md +0 -161
  197. package/.agent/skills/systematic-debugging/SKILL.md +0 -120
  198. package/.agent/skills/tailwind-patterns/SKILL.md +0 -269
  199. package/.agent/skills/tdd-workflow/SKILL.md +0 -148
  200. package/.agent/skills/telegram-agentic-gateway/SKILL.md +0 -80
  201. package/.agent/skills/testing-patterns/SKILL.md +0 -178
  202. package/.agent/skills/testing-patterns/scripts/test_runner.py +0 -219
  203. package/.agent/skills/vulnerability-scanner/SKILL.md +0 -276
  204. package/.agent/skills/vulnerability-scanner/checklists.md +0 -121
  205. package/.agent/skills/vulnerability-scanner/scripts/security_scan.py +0 -458
  206. package/.agent/skills/web-design-guidelines/SKILL.md +0 -57
  207. package/.agent/skills/webapp-testing/SKILL.md +0 -187
  208. package/.agent/skills/webapp-testing/scripts/playwright_runner.py +0 -173
  209. package/.agent/workflows/brainstorm.md +0 -113
  210. package/.agent/workflows/create.md +0 -59
  211. package/.agent/workflows/debug.md +0 -103
  212. package/.agent/workflows/deploy.md +0 -176
  213. package/.agent/workflows/enhance.md +0 -63
  214. package/.agent/workflows/orchestrate.md +0 -237
  215. package/.agent/workflows/plan.md +0 -89
  216. package/.agent/workflows/preview.md +0 -81
  217. package/.agent/workflows/status.md +0 -86
  218. package/.agent/workflows/test.md +0 -144
  219. package/.agent/workflows/ui-ux-pro-max.md +0 -296
@@ -1,490 +0,0 @@
1
- # 3. Server-Side Performance
2
-
3
- > **Impact:** HIGH
4
- > **Focus:** Optimizing server-side rendering and data fetching eliminates server-side waterfalls and reduces response times.
5
-
6
- ---
7
-
8
- ## Overview
9
-
10
- This section contains **7 rules** focused on server-side performance.
11
-
12
- ---
13
-
14
- ## Rule 3.1: Authenticate Server Actions Like API Routes
15
-
16
- **Impact:** CRITICAL
17
- **Tags:** server, server-actions, authentication, security, authorization
18
-
19
- ## Authenticate Server Actions Like API Routes
20
-
21
- **Impact: CRITICAL (prevents unauthorized access to server mutations)**
22
-
23
- Server Actions (functions with `"use server"`) are exposed as public endpoints, just like API routes. Always verify authentication and authorization **inside** each Server Action—do not rely solely on middleware, layout guards, or page-level checks, as Server Actions can be invoked directly.
24
-
25
- Next.js documentation explicitly states: "Treat Server Actions with the same security considerations as public-facing API endpoints, and verify if the user is allowed to perform a mutation."
26
-
27
- **Incorrect (no authentication check):**
28
-
29
- ```typescript
30
- 'use server'
31
-
32
- export async function deleteUser(userId: string) {
33
- // Anyone can call this! No auth check
34
- await db.user.delete({ where: { id: userId } })
35
- return { success: true }
36
- }
37
- ```
38
-
39
- **Correct (authentication inside the action):**
40
-
41
- ```typescript
42
- 'use server'
43
-
44
- import { verifySession } from '@/lib/auth'
45
- import { unauthorized } from '@/lib/errors'
46
-
47
- export async function deleteUser(userId: string) {
48
- // Always check auth inside the action
49
- const session = await verifySession()
50
-
51
- if (!session) {
52
- throw unauthorized('Must be logged in')
53
- }
54
-
55
- // Check authorization too
56
- if (session.user.role !== 'admin' && session.user.id !== userId) {
57
- throw unauthorized('Cannot delete other users')
58
- }
59
-
60
- await db.user.delete({ where: { id: userId } })
61
- return { success: true }
62
- }
63
- ```
64
-
65
- **With input validation:**
66
-
67
- ```typescript
68
- 'use server'
69
-
70
- import { verifySession } from '@/lib/auth'
71
- import { z } from 'zod'
72
-
73
- const updateProfileSchema = z.object({
74
- userId: z.string().uuid(),
75
- name: z.string().min(1).max(100),
76
- email: z.string().email()
77
- })
78
-
79
- export async function updateProfile(data: unknown) {
80
- // Validate input first
81
- const validated = updateProfileSchema.parse(data)
82
-
83
- // Then authenticate
84
- const session = await verifySession()
85
- if (!session) {
86
- throw new Error('Unauthorized')
87
- }
88
-
89
- // Then authorize
90
- if (session.user.id !== validated.userId) {
91
- throw new Error('Can only update own profile')
92
- }
93
-
94
- // Finally perform the mutation
95
- await db.user.update({
96
- where: { id: validated.userId },
97
- data: {
98
- name: validated.name,
99
- email: validated.email
100
- }
101
- })
102
-
103
- return { success: true }
104
- }
105
- ```
106
-
107
- Reference: [https://nextjs.org/docs/app/guides/authentication](https://nextjs.org/docs/app/guides/authentication)
108
-
109
- ---
110
-
111
- ## Rule 3.2: Avoid Duplicate Serialization in RSC Props
112
-
113
- **Impact:** LOW
114
- **Tags:** server, rsc, serialization, props, client-components
115
-
116
- ## Avoid Duplicate Serialization in RSC Props
117
-
118
- **Impact: LOW (reduces network payload by avoiding duplicate serialization)**
119
-
120
- RSC→client serialization deduplicates by object reference, not value. Same reference = serialized once; new reference = serialized again. Do transformations (`.toSorted()`, `.filter()`, `.map()`) in client, not server.
121
-
122
- **Incorrect (duplicates array):**
123
-
124
- ```tsx
125
- // RSC: sends 6 strings (2 arrays × 3 items)
126
- <ClientList usernames={usernames} usernamesOrdered={usernames.toSorted()} />
127
- ```
128
-
129
- **Correct (sends 3 strings):**
130
-
131
- ```tsx
132
- // RSC: send once
133
- <ClientList usernames={usernames} />
134
-
135
- // Client: transform there
136
- 'use client'
137
- const sorted = useMemo(() => [...usernames].sort(), [usernames])
138
- ```
139
-
140
- **Nested deduplication behavior:**
141
-
142
- Deduplication works recursively. Impact varies by data type:
143
-
144
- - `string[]`, `number[]`, `boolean[]`: **HIGH impact** - array + all primitives fully duplicated
145
- - `object[]`: **LOW impact** - array duplicated, but nested objects deduplicated by reference
146
-
147
- ```tsx
148
- // string[] - duplicates everything
149
- usernames={['a','b']} sorted={usernames.toSorted()} // sends 4 strings
150
-
151
- // object[] - duplicates array structure only
152
- users={[{id:1},{id:2}]} sorted={users.toSorted()} // sends 2 arrays + 2 unique objects (not 4)
153
- ```
154
-
155
- **Operations breaking deduplication (create new references):**
156
-
157
- - Arrays: `.toSorted()`, `.filter()`, `.map()`, `.slice()`, `[...arr]`
158
- - Objects: `{...obj}`, `Object.assign()`, `structuredClone()`, `JSON.parse(JSON.stringify())`
159
-
160
- **More examples:**
161
-
162
- ```tsx
163
- // ❌ Bad
164
- <C users={users} active={users.filter(u => u.active)} />
165
- <C product={product} productName={product.name} />
166
-
167
- // ✅ Good
168
- <C users={users} />
169
- <C product={product} />
170
- // Do filtering/destructuring in client
171
- ```
172
-
173
- **Exception:** Pass derived data when transformation is expensive or client doesn't need original.
174
-
175
- ---
176
-
177
- ## Rule 3.3: Cross-Request LRU Caching
178
-
179
- **Impact:** HIGH
180
- **Tags:** server, cache, lru, cross-request
181
-
182
- ## Cross-Request LRU Caching
183
-
184
- `React.cache()` only works within one request. For data shared across sequential requests (user clicks button A then button B), use an LRU cache.
185
-
186
- **Implementation:**
187
-
188
- ```typescript
189
- import { LRUCache } from 'lru-cache'
190
-
191
- const cache = new LRUCache<string, any>({
192
- max: 1000,
193
- ttl: 5 * 60 * 1000 // 5 minutes
194
- })
195
-
196
- export async function getUser(id: string) {
197
- const cached = cache.get(id)
198
- if (cached) return cached
199
-
200
- const user = await db.user.findUnique({ where: { id } })
201
- cache.set(id, user)
202
- return user
203
- }
204
-
205
- // Request 1: DB query, result cached
206
- // Request 2: cache hit, no DB query
207
- ```
208
-
209
- Use when sequential user actions hit multiple endpoints needing the same data within seconds.
210
-
211
- **With Vercel's [Fluid Compute](https://vercel.com/docs/fluid-compute):** LRU caching is especially effective because multiple concurrent requests can share the same function instance and cache. This means the cache persists across requests without needing external storage like Redis.
212
-
213
- **In traditional serverless:** Each invocation runs in isolation, so consider Redis for cross-process caching.
214
-
215
- Reference: [https://github.com/isaacs/node-lru-cache](https://github.com/isaacs/node-lru-cache)
216
-
217
- ---
218
-
219
- ## Rule 3.4: Minimize Serialization at RSC Boundaries
220
-
221
- **Impact:** HIGH
222
- **Tags:** server, rsc, serialization, props
223
-
224
- ## Minimize Serialization at RSC Boundaries
225
-
226
- The React Server/Client boundary serializes all object properties into strings and embeds them in the HTML response and subsequent RSC requests. This serialized data directly impacts page weight and load time, so **size matters a lot**. Only pass fields that the client actually uses.
227
-
228
- **Incorrect (serializes all 50 fields):**
229
-
230
- ```tsx
231
- async function Page() {
232
- const user = await fetchUser() // 50 fields
233
- return <Profile user={user} />
234
- }
235
-
236
- 'use client'
237
- function Profile({ user }: { user: User }) {
238
- return <div>{user.name}</div> // uses 1 field
239
- }
240
- ```
241
-
242
- **Correct (serializes only 1 field):**
243
-
244
- ```tsx
245
- async function Page() {
246
- const user = await fetchUser()
247
- return <Profile name={user.name} />
248
- }
249
-
250
- 'use client'
251
- function Profile({ name }: { name: string }) {
252
- return <div>{name}</div>
253
- }
254
- ```
255
-
256
- ---
257
-
258
- ## Rule 3.5: Parallel Data Fetching with Component Composition
259
-
260
- **Impact:** CRITICAL
261
- **Tags:** server, rsc, parallel-fetching, composition
262
-
263
- ## Parallel Data Fetching with Component Composition
264
-
265
- React Server Components execute sequentially within a tree. Restructure with composition to parallelize data fetching.
266
-
267
- **Incorrect (Sidebar waits for Page's fetch to complete):**
268
-
269
- ```tsx
270
- export default async function Page() {
271
- const header = await fetchHeader()
272
- return (
273
- <div>
274
- <div>{header}</div>
275
- <Sidebar />
276
- </div>
277
- )
278
- }
279
-
280
- async function Sidebar() {
281
- const items = await fetchSidebarItems()
282
- return <nav>{items.map(renderItem)}</nav>
283
- }
284
- ```
285
-
286
- **Correct (both fetch simultaneously):**
287
-
288
- ```tsx
289
- async function Header() {
290
- const data = await fetchHeader()
291
- return <div>{data}</div>
292
- }
293
-
294
- async function Sidebar() {
295
- const items = await fetchSidebarItems()
296
- return <nav>{items.map(renderItem)}</nav>
297
- }
298
-
299
- export default function Page() {
300
- return (
301
- <div>
302
- <Header />
303
- <Sidebar />
304
- </div>
305
- )
306
- }
307
- ```
308
-
309
- **Alternative with children prop:**
310
-
311
- ```tsx
312
- async function Header() {
313
- const data = await fetchHeader()
314
- return <div>{data}</div>
315
- }
316
-
317
- async function Sidebar() {
318
- const items = await fetchSidebarItems()
319
- return <nav>{items.map(renderItem)}</nav>
320
- }
321
-
322
- function Layout({ children }: { children: ReactNode }) {
323
- return (
324
- <div>
325
- <Header />
326
- {children}
327
- </div>
328
- )
329
- }
330
-
331
- export default function Page() {
332
- return (
333
- <Layout>
334
- <Sidebar />
335
- </Layout>
336
- )
337
- }
338
- ```
339
-
340
- ---
341
-
342
- ## Rule 3.6: Per-Request Deduplication with React.cache()
343
-
344
- **Impact:** MEDIUM
345
- **Tags:** server, cache, react-cache, deduplication
346
-
347
- ## Per-Request Deduplication with React.cache()
348
-
349
- Use `React.cache()` for server-side request deduplication. Authentication and database queries benefit most.
350
-
351
- **Usage:**
352
-
353
- ```typescript
354
- import { cache } from 'react'
355
-
356
- export const getCurrentUser = cache(async () => {
357
- const session = await auth()
358
- if (!session?.user?.id) return null
359
- return await db.user.findUnique({
360
- where: { id: session.user.id }
361
- })
362
- })
363
- ```
364
-
365
- Within a single request, multiple calls to `getCurrentUser()` execute the query only once.
366
-
367
- **Avoid inline objects as arguments:**
368
-
369
- `React.cache()` uses shallow equality (`Object.is`) to determine cache hits. Inline objects create new references each call, preventing cache hits.
370
-
371
- **Incorrect (always cache miss):**
372
-
373
- ```typescript
374
- const getUser = cache(async (params: { uid: number }) => {
375
- return await db.user.findUnique({ where: { id: params.uid } })
376
- })
377
-
378
- // Each call creates new object, never hits cache
379
- getUser({ uid: 1 })
380
- getUser({ uid: 1 }) // Cache miss, runs query again
381
- ```
382
-
383
- **Correct (cache hit):**
384
-
385
- ```typescript
386
- const getUser = cache(async (uid: number) => {
387
- return await db.user.findUnique({ where: { id: uid } })
388
- })
389
-
390
- // Primitive args use value equality
391
- getUser(1)
392
- getUser(1) // Cache hit, returns cached result
393
- ```
394
-
395
- If you must pass objects, pass the same reference:
396
-
397
- ```typescript
398
- const params = { uid: 1 }
399
- getUser(params) // Query runs
400
- getUser(params) // Cache hit (same reference)
401
- ```
402
-
403
- **Next.js-Specific Note:**
404
-
405
- In Next.js, the `fetch` API is automatically extended with request memoization. Requests with the same URL and options are automatically deduplicated within a single request, so you don't need `React.cache()` for `fetch` calls. However, `React.cache()` is still essential for other async tasks:
406
-
407
- - Database queries (Prisma, Drizzle, etc.)
408
- - Heavy computations
409
- - Authentication checks
410
- - File system operations
411
- - Any non-fetch async work
412
-
413
- Use `React.cache()` to deduplicate these operations across your component tree.
414
-
415
- Reference: [React.cache documentation](https://react.dev/reference/react/cache)
416
-
417
- ---
418
-
419
- ## Rule 3.7: Use after() for Non-Blocking Operations
420
-
421
- **Impact:** MEDIUM
422
- **Tags:** server, async, logging, analytics, side-effects
423
-
424
- ## Use after() for Non-Blocking Operations
425
-
426
- Use Next.js's `after()` to schedule work that should execute after a response is sent. This prevents logging, analytics, and other side effects from blocking the response.
427
-
428
- **Incorrect (blocks response):**
429
-
430
- ```tsx
431
- import { logUserAction } from '@/app/utils'
432
-
433
- export async function POST(request: Request) {
434
- // Perform mutation
435
- await updateDatabase(request)
436
-
437
- // Logging blocks the response
438
- const userAgent = request.headers.get('user-agent') || 'unknown'
439
- await logUserAction({ userAgent })
440
-
441
- return new Response(JSON.stringify({ status: 'success' }), {
442
- status: 200,
443
- headers: { 'Content-Type': 'application/json' }
444
- })
445
- }
446
- ```
447
-
448
- **Correct (non-blocking):**
449
-
450
- ```tsx
451
- import { after } from 'next/server'
452
- import { headers, cookies } from 'next/headers'
453
- import { logUserAction } from '@/app/utils'
454
-
455
- export async function POST(request: Request) {
456
- // Perform mutation
457
- await updateDatabase(request)
458
-
459
- // Log after response is sent
460
- after(async () => {
461
- const userAgent = (await headers()).get('user-agent') || 'unknown'
462
- const sessionCookie = (await cookies()).get('session-id')?.value || 'anonymous'
463
-
464
- logUserAction({ sessionCookie, userAgent })
465
- })
466
-
467
- return new Response(JSON.stringify({ status: 'success' }), {
468
- status: 200,
469
- headers: { 'Content-Type': 'application/json' }
470
- })
471
- }
472
- ```
473
-
474
- The response is sent immediately while logging happens in the background.
475
-
476
- **Common use cases:**
477
-
478
- - Analytics tracking
479
- - Audit logging
480
- - Sending notifications
481
- - Cache invalidation
482
- - Cleanup tasks
483
-
484
- **Important notes:**
485
-
486
- - `after()` runs even if the response fails or redirects
487
- - Works in Server Actions, Route Handlers, and Server Components
488
-
489
- Reference: [https://nextjs.org/docs/app/api-reference/functions/after](https://nextjs.org/docs/app/api-reference/functions/after)
490
-