tribunal-kit 3.0.0 → 3.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 (226) hide show
  1. package/.agent/ARCHITECTURE.md +99 -99
  2. package/.agent/GEMINI.md +52 -52
  3. package/.agent/agents/accessibility-reviewer.md +187 -220
  4. package/.agent/agents/ai-code-reviewer.md +199 -233
  5. package/.agent/agents/backend-specialist.md +215 -238
  6. package/.agent/agents/code-archaeologist.md +161 -181
  7. package/.agent/agents/database-architect.md +184 -207
  8. package/.agent/agents/debugger.md +191 -218
  9. package/.agent/agents/dependency-reviewer.md +103 -136
  10. package/.agent/agents/devops-engineer.md +218 -238
  11. package/.agent/agents/documentation-writer.md +201 -221
  12. package/.agent/agents/explorer-agent.md +160 -180
  13. package/.agent/agents/frontend-reviewer.md +160 -194
  14. package/.agent/agents/frontend-specialist.md +248 -237
  15. package/.agent/agents/game-developer.md +48 -52
  16. package/.agent/agents/logic-reviewer.md +116 -149
  17. package/.agent/agents/mobile-developer.md +200 -223
  18. package/.agent/agents/mobile-reviewer.md +162 -195
  19. package/.agent/agents/orchestrator.md +181 -211
  20. package/.agent/agents/penetration-tester.md +157 -174
  21. package/.agent/agents/performance-optimizer.md +183 -203
  22. package/.agent/agents/performance-reviewer.md +178 -211
  23. package/.agent/agents/product-manager.md +142 -162
  24. package/.agent/agents/product-owner.md +6 -25
  25. package/.agent/agents/project-planner.md +142 -162
  26. package/.agent/agents/qa-automation-engineer.md +225 -242
  27. package/.agent/agents/security-auditor.md +174 -194
  28. package/.agent/agents/seo-specialist.md +193 -213
  29. package/.agent/agents/sql-reviewer.md +161 -194
  30. package/.agent/agents/supervisor-agent.md +184 -203
  31. package/.agent/agents/swarm-worker-contracts.md +17 -17
  32. package/.agent/agents/swarm-worker-registry.md +46 -46
  33. package/.agent/agents/test-coverage-reviewer.md +160 -193
  34. package/.agent/agents/test-engineer.md +0 -21
  35. package/.agent/agents/type-safety-reviewer.md +175 -208
  36. package/.agent/patterns/generator.md +9 -9
  37. package/.agent/patterns/inversion.md +12 -12
  38. package/.agent/patterns/pipeline.md +9 -9
  39. package/.agent/patterns/reviewer.md +13 -13
  40. package/.agent/patterns/tool-wrapper.md +9 -9
  41. package/.agent/rules/GEMINI.md +63 -63
  42. package/.agent/scripts/compress_skills.py +167 -0
  43. package/.agent/scripts/consolidate_skills.py +173 -0
  44. package/.agent/scripts/deep_compress.py +202 -0
  45. package/.agent/scripts/minify_context.py +80 -0
  46. package/.agent/scripts/security_scan.py +1 -1
  47. package/.agent/scripts/strip_tribunal.py +41 -0
  48. package/.agent/skills/agent-organizer/SKILL.md +92 -126
  49. package/.agent/skills/agentic-patterns/SKILL.md +0 -70
  50. package/.agent/skills/ai-prompt-injection-defense/SKILL.md +126 -160
  51. package/.agent/skills/api-patterns/SKILL.md +123 -215
  52. package/.agent/skills/api-security-auditor/SKILL.md +143 -177
  53. package/.agent/skills/app-builder/SKILL.md +326 -50
  54. package/.agent/skills/app-builder/templates/SKILL.md +13 -15
  55. package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +16 -16
  56. package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +22 -22
  57. package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +18 -18
  58. package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +20 -20
  59. package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +17 -17
  60. package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +18 -18
  61. package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +21 -21
  62. package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +19 -19
  63. package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +26 -26
  64. package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +26 -26
  65. package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +19 -19
  66. package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +18 -18
  67. package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +20 -20
  68. package/.agent/skills/appflow-wireframe/SKILL.md +87 -121
  69. package/.agent/skills/architecture/SKILL.md +82 -252
  70. package/.agent/skills/authentication-best-practices/SKILL.md +139 -173
  71. package/.agent/skills/bash-linux/SKILL.md +120 -154
  72. package/.agent/skills/behavioral-modes/SKILL.md +8 -69
  73. package/.agent/skills/brainstorming/SKILL.md +428 -104
  74. package/.agent/skills/building-native-ui/SKILL.md +143 -174
  75. package/.agent/skills/clean-code/SKILL.md +323 -360
  76. package/.agent/skills/code-review-checklist/SKILL.md +0 -62
  77. package/.agent/skills/config-validator/SKILL.md +107 -141
  78. package/.agent/skills/csharp-developer/SKILL.md +468 -528
  79. package/.agent/skills/database-design/SKILL.md +104 -369
  80. package/.agent/skills/deployment-procedures/SKILL.md +111 -145
  81. package/.agent/skills/devops-engineer/SKILL.md +295 -332
  82. package/.agent/skills/devops-incident-responder/SKILL.md +79 -113
  83. package/.agent/skills/doc.md +5 -5
  84. package/.agent/skills/documentation-templates/SKILL.md +19 -63
  85. package/.agent/skills/edge-computing/SKILL.md +123 -157
  86. package/.agent/skills/extract-design-system/SKILL.md +100 -134
  87. package/.agent/skills/framer-motion-expert/SKILL.md +111 -855
  88. package/.agent/skills/frontend-design/SKILL.md +151 -499
  89. package/.agent/skills/game-design-expert/SKILL.md +71 -105
  90. package/.agent/skills/game-engineering-expert/SKILL.md +88 -122
  91. package/.agent/skills/geo-fundamentals/SKILL.md +89 -124
  92. package/.agent/skills/github-operations/SKILL.md +279 -314
  93. package/.agent/skills/gsap-expert/SKILL.md +119 -826
  94. package/.agent/skills/i18n-localization/SKILL.md +104 -138
  95. package/.agent/skills/intelligent-routing/SKILL.md +159 -127
  96. package/.agent/skills/lint-and-validate/SKILL.md +8 -52
  97. package/.agent/skills/llm-engineering/SKILL.md +344 -357
  98. package/.agent/skills/local-first/SKILL.md +120 -154
  99. package/.agent/skills/mcp-builder/SKILL.md +84 -118
  100. package/.agent/skills/mobile-design/SKILL.md +213 -219
  101. package/.agent/skills/motion-engineering/SKILL.md +184 -0
  102. package/.agent/skills/nextjs-react-expert/SKILL.md +99 -698
  103. package/.agent/skills/nodejs-best-practices/SKILL.md +498 -559
  104. package/.agent/skills/observability/SKILL.md +293 -330
  105. package/.agent/skills/parallel-agents/SKILL.md +88 -122
  106. package/.agent/skills/performance-profiling/SKILL.md +217 -254
  107. package/.agent/skills/plan-writing/SKILL.md +84 -118
  108. package/.agent/skills/platform-engineer/SKILL.md +89 -123
  109. package/.agent/skills/playwright-best-practices/SKILL.md +128 -162
  110. package/.agent/skills/powershell-windows/SKILL.md +112 -146
  111. package/.agent/skills/python-patterns/SKILL.md +7 -35
  112. package/.agent/skills/python-pro/SKILL.md +148 -754
  113. package/.agent/skills/react-specialist/SKILL.md +123 -827
  114. package/.agent/skills/readme-builder/SKILL.md +15 -85
  115. package/.agent/skills/realtime-patterns/SKILL.md +269 -304
  116. package/.agent/skills/red-team-tactics/SKILL.md +10 -51
  117. package/.agent/skills/rust-pro/SKILL.md +623 -701
  118. package/.agent/skills/seo-fundamentals/SKILL.md +120 -154
  119. package/.agent/skills/server-management/SKILL.md +156 -190
  120. package/.agent/skills/shadcn-ui-expert/SKILL.md +172 -206
  121. package/.agent/skills/skill-creator/SKILL.md +18 -58
  122. package/.agent/skills/sql-pro/SKILL.md +579 -633
  123. package/.agent/skills/supabase-postgres-best-practices/SKILL.md +28 -68
  124. package/.agent/skills/swiftui-expert/SKILL.md +142 -176
  125. package/.agent/skills/systematic-debugging/SKILL.md +84 -118
  126. package/.agent/skills/tailwind-patterns/SKILL.md +516 -576
  127. package/.agent/skills/tdd-workflow/SKILL.md +103 -137
  128. package/.agent/skills/test-result-analyzer/SKILL.md +33 -73
  129. package/.agent/skills/testing-patterns/SKILL.md +512 -573
  130. package/.agent/skills/trend-researcher/SKILL.md +30 -71
  131. package/.agent/skills/ui-ux-pro-max/SKILL.md +0 -41
  132. package/.agent/skills/ui-ux-researcher/SKILL.md +51 -91
  133. package/.agent/skills/vue-expert/SKILL.md +127 -866
  134. package/.agent/skills/vulnerability-scanner/SKILL.md +354 -269
  135. package/.agent/skills/web-accessibility-auditor/SKILL.md +159 -193
  136. package/.agent/skills/web-design-guidelines/SKILL.md +17 -61
  137. package/.agent/skills/webapp-testing/SKILL.md +111 -145
  138. package/.agent/skills/whimsy-injector/SKILL.md +58 -132
  139. package/.agent/skills/workflow-optimizer/SKILL.md +28 -68
  140. package/.agent/workflows/api-tester.md +151 -151
  141. package/.agent/workflows/audit.md +127 -138
  142. package/.agent/workflows/brainstorm.md +110 -110
  143. package/.agent/workflows/changelog.md +112 -112
  144. package/.agent/workflows/create.md +124 -124
  145. package/.agent/workflows/debug.md +165 -189
  146. package/.agent/workflows/deploy.md +180 -189
  147. package/.agent/workflows/enhance.md +128 -151
  148. package/.agent/workflows/fix.md +114 -135
  149. package/.agent/workflows/generate.md +12 -4
  150. package/.agent/workflows/migrate.md +160 -160
  151. package/.agent/workflows/orchestrate.md +168 -168
  152. package/.agent/workflows/performance-benchmarker.md +114 -123
  153. package/.agent/workflows/plan.md +173 -173
  154. package/.agent/workflows/preview.md +80 -80
  155. package/.agent/workflows/refactor.md +161 -183
  156. package/.agent/workflows/review-ai.md +101 -129
  157. package/.agent/workflows/review.md +116 -116
  158. package/.agent/workflows/session.md +94 -94
  159. package/.agent/workflows/status.md +79 -79
  160. package/.agent/workflows/strengthen-skills.md +138 -139
  161. package/.agent/workflows/swarm.md +179 -179
  162. package/.agent/workflows/test.md +189 -211
  163. package/.agent/workflows/tribunal-backend.md +93 -113
  164. package/.agent/workflows/tribunal-database.md +94 -115
  165. package/.agent/workflows/tribunal-frontend.md +95 -118
  166. package/.agent/workflows/tribunal-full.md +92 -133
  167. package/.agent/workflows/tribunal-mobile.md +94 -119
  168. package/.agent/workflows/tribunal-performance.md +109 -133
  169. package/.agent/workflows/ui-ux-pro-max.md +122 -143
  170. package/package.json +1 -1
  171. package/.agent/skills/api-patterns/api-style.md +0 -42
  172. package/.agent/skills/api-patterns/auth.md +0 -24
  173. package/.agent/skills/api-patterns/documentation.md +0 -26
  174. package/.agent/skills/api-patterns/graphql.md +0 -41
  175. package/.agent/skills/api-patterns/rate-limiting.md +0 -31
  176. package/.agent/skills/api-patterns/response.md +0 -37
  177. package/.agent/skills/api-patterns/rest.md +0 -40
  178. package/.agent/skills/api-patterns/security-testing.md +0 -122
  179. package/.agent/skills/api-patterns/trpc.md +0 -41
  180. package/.agent/skills/api-patterns/versioning.md +0 -22
  181. package/.agent/skills/app-builder/agent-coordination.md +0 -71
  182. package/.agent/skills/app-builder/feature-building.md +0 -53
  183. package/.agent/skills/app-builder/project-detection.md +0 -34
  184. package/.agent/skills/app-builder/scaffolding.md +0 -118
  185. package/.agent/skills/app-builder/tech-stack.md +0 -40
  186. package/.agent/skills/architecture/context-discovery.md +0 -43
  187. package/.agent/skills/architecture/examples.md +0 -94
  188. package/.agent/skills/architecture/pattern-selection.md +0 -68
  189. package/.agent/skills/architecture/patterns-reference.md +0 -50
  190. package/.agent/skills/architecture/trade-off-analysis.md +0 -77
  191. package/.agent/skills/brainstorming/dynamic-questioning.md +0 -360
  192. package/.agent/skills/database-design/database-selection.md +0 -43
  193. package/.agent/skills/database-design/indexing.md +0 -39
  194. package/.agent/skills/database-design/migrations.md +0 -48
  195. package/.agent/skills/database-design/optimization.md +0 -36
  196. package/.agent/skills/database-design/orm-selection.md +0 -30
  197. package/.agent/skills/database-design/schema-design.md +0 -56
  198. package/.agent/skills/frontend-design/animation-guide.md +0 -331
  199. package/.agent/skills/frontend-design/color-system.md +0 -329
  200. package/.agent/skills/frontend-design/decision-trees.md +0 -418
  201. package/.agent/skills/frontend-design/motion-graphics.md +0 -306
  202. package/.agent/skills/frontend-design/typography-system.md +0 -363
  203. package/.agent/skills/frontend-design/ux-psychology.md +0 -1116
  204. package/.agent/skills/frontend-design/visual-effects.md +0 -383
  205. package/.agent/skills/intelligent-routing/router-manifest.md +0 -65
  206. package/.agent/skills/mobile-design/decision-trees.md +0 -516
  207. package/.agent/skills/mobile-design/mobile-backend.md +0 -491
  208. package/.agent/skills/mobile-design/mobile-color-system.md +0 -420
  209. package/.agent/skills/mobile-design/mobile-debugging.md +0 -122
  210. package/.agent/skills/mobile-design/mobile-design-thinking.md +0 -357
  211. package/.agent/skills/mobile-design/mobile-navigation.md +0 -458
  212. package/.agent/skills/mobile-design/mobile-performance.md +0 -767
  213. package/.agent/skills/mobile-design/mobile-testing.md +0 -356
  214. package/.agent/skills/mobile-design/mobile-typography.md +0 -433
  215. package/.agent/skills/mobile-design/platform-android.md +0 -666
  216. package/.agent/skills/mobile-design/platform-ios.md +0 -561
  217. package/.agent/skills/mobile-design/touch-psychology.md +0 -537
  218. package/.agent/skills/nextjs-react-expert/1-async-eliminating-waterfalls.md +0 -312
  219. package/.agent/skills/nextjs-react-expert/2-bundle-bundle-size-optimization.md +0 -240
  220. package/.agent/skills/nextjs-react-expert/3-server-server-side-performance.md +0 -490
  221. package/.agent/skills/nextjs-react-expert/4-client-client-side-data-fetching.md +0 -264
  222. package/.agent/skills/nextjs-react-expert/5-rerender-re-render-optimization.md +0 -581
  223. package/.agent/skills/nextjs-react-expert/6-rendering-rendering-performance.md +0 -432
  224. package/.agent/skills/nextjs-react-expert/7-js-javascript-performance.md +0 -684
  225. package/.agent/skills/nextjs-react-expert/8-advanced-advanced-patterns.md +0 -150
  226. package/.agent/skills/vulnerability-scanner/checklists.md +0 -121
@@ -1,559 +1,498 @@
1
- ---
2
- name: nodejs-best-practices
3
- description: Node.js 22+ production mastery. ES Modules, async patterns, Express/Fastify/Hono, middleware architecture, error handling, streaming, worker threads, environment config, security hardening, process management, and deployment patterns. Use when building Node.js servers, APIs, CLI tools, or any server-side JavaScript.
4
- allowed-tools: Read, Write, Edit, Glob, Grep
5
- version: 2.0.0
6
- last-updated: 2026-04-01
7
- applies-to-model: gemini-2.5-pro, claude-3-7-sonnet
8
- ---
9
-
10
- # Node.js Best Practices — Node 22+ Production Mastery
11
-
12
- > Node.js is not "JavaScript on the server." It is an event-driven, non-blocking I/O runtime.
13
- > Every callback without error handling is a memory leak waiting to happen.
14
- > Every unhandled promise rejection is a crashed process in production.
15
-
16
- ---
17
-
18
- ## ES Modules (Mandatory)
19
-
20
- ```json
21
- // package.json — ALWAYS set type to module
22
- {
23
- "type": "module",
24
- "engines": { "node": ">=22" }
25
- }
26
- ```
27
-
28
- ```typescript
29
- // ESM imports (modern Node.js)
30
- import { readFile, writeFile } from "node:fs/promises";
31
- import { join, resolve } from "node:path";
32
- import { createServer } from "node:http";
33
- import { EventEmitter } from "node:events";
34
-
35
- // ❌ HALLUCINATION TRAP: Use node: protocol prefix for built-in modules
36
- // ❌ import fs from "fs"; ambiguous (could be npm package)
37
- // ✅ import fs from "node:fs"; ← explicitly a Node.js built-in
38
-
39
- // HALLUCINATION TRAP: Do NOT use require() in ESM projects
40
- // ❌ const fs = require("fs"); ← CommonJS (legacy)
41
- // ✅ import fs from "node:fs/promises"; ← ESM
42
-
43
- // Dynamic imports (for conditional loading)
44
- const module = await import("./heavy-module.js");
45
- ```
46
-
47
- ---
48
-
49
- ## Framework Selection
50
-
51
- ```
52
- ┌────────────────────────────────────────────────────────────┐
53
- When to Use What
54
- ├────────────────────────────────────────────────────────────┤
55
- Express Legacy projects, extensive middleware ecosystem
56
- │ Fastify │ Performance-critical APIs, schema validation │
57
- │ Hono │ Edge/serverless, multi-runtime (Node/Deno/Bun)│
58
- │ tRPC │ Full-stack TypeScript (Next.js + React Query) │
59
- Raw http │ Learning, minimal proxies, health checks │
60
- └────────────────────────────────────────────────────────────┘
61
- ```
62
-
63
- ### Fastify (Recommended)
64
-
65
- ```typescript
66
- import Fastify from "fastify";
67
- import { z } from "zod";
68
-
69
- const app = Fastify({
70
- logger: {
71
- level: process.env.LOG_LEVEL ?? "info",
72
- transport: process.env.NODE_ENV === "development"
73
- ? { target: "pino-pretty" }
74
- : undefined,
75
- },
76
- });
77
-
78
- // Schema validation with Zod → Fastify schema
79
- const CreateUserSchema = z.object({
80
- name: z.string().min(2).max(100),
81
- email: z.string().email(),
82
- role: z.enum(["admin", "user"]).default("user"),
83
- });
84
-
85
- type CreateUserBody = z.infer<typeof CreateUserSchema>;
86
-
87
- app.post<{ Body: CreateUserBody }>("/users", {
88
- schema: {
89
- body: {
90
- type: "object",
91
- required: ["name", "email"],
92
- properties: {
93
- name: { type: "string", minLength: 2 },
94
- email: { type: "string", format: "email" },
95
- role: { type: "string", enum: ["admin", "user"] },
96
- },
97
- },
98
- },
99
- }, async (request, reply) => {
100
- const validated = CreateUserSchema.parse(request.body);
101
- const user = await createUser(validated);
102
- return reply.status(201).send(user);
103
- });
104
-
105
- // Graceful shutdown
106
- const start = async () => {
107
- try {
108
- await app.listen({ port: 3000, host: "0.0.0.0" });
109
- } catch (err) {
110
- app.log.error(err);
111
- process.exit(1);
112
- }
113
- };
114
-
115
- start();
116
- ```
117
-
118
- ### Hono (Edge-First)
119
-
120
- ```typescript
121
- import { Hono } from "hono";
122
- import { cors } from "hono/cors";
123
- import { logger } from "hono/logger";
124
- import { zValidator } from "@hono/zod-validator";
125
- import { z } from "zod";
126
-
127
- const app = new Hono();
128
-
129
- app.use("*", logger());
130
- app.use("*", cors({ origin: "https://myapp.com" }));
131
-
132
- const createUserSchema = z.object({
133
- name: z.string().min(2),
134
- email: z.string().email(),
135
- });
136
-
137
- app.post("/users", zValidator("json", createUserSchema), async (c) => {
138
- const body = c.req.valid("json");
139
- const user = await createUser(body);
140
- return c.json(user, 201);
141
- });
142
-
143
- app.get("/health", (c) => c.json({ status: "ok" }));
144
-
145
- export default app; // works in Node, Deno, Bun, Cloudflare Workers
146
- ```
147
-
148
- ---
149
-
150
- ## Error Handling
151
-
152
- ### Global Error Handlers
153
-
154
- ```typescript
155
- // MANDATORY: Handle unhandled rejections and exceptions
156
- process.on("unhandledRejection", (reason, promise) => {
157
- console.error("Unhandled Rejection at:", promise, "reason:", reason);
158
- // Log to error tracking service (Sentry, etc.)
159
- // Gracefully shutdown
160
- process.exit(1);
161
- });
162
-
163
- process.on("uncaughtException", (error) => {
164
- console.error("Uncaught Exception:", error);
165
- // Log to error tracking service
166
- process.exit(1); // MUST exit state is corrupted
167
- });
168
-
169
- // ❌ HALLUCINATION TRAP: After uncaughtException, the process MUST exit
170
- // The process is in an undefined state — continuing is dangerous
171
- // process.on("uncaughtException", (err) => { console.log(err); }); // continues running
172
- // ✅ process.on("uncaughtException", (err) => { log(err); process.exit(1); });
173
- ```
174
-
175
- ### Application Error Classes
176
-
177
- ```typescript
178
- export class AppError extends Error {
179
- constructor(
180
- message: string,
181
- public statusCode: number = 500,
182
- public code: string = "INTERNAL_ERROR",
183
- public isOperational: boolean = true,
184
- ) {
185
- super(message);
186
- this.name = "AppError";
187
- Error.captureStackTrace(this, this.constructor);
188
- }
189
- }
190
-
191
- export class NotFoundError extends AppError {
192
- constructor(resource: string, id: string) {
193
- super(`${resource} '${id}' not found`, 404, "NOT_FOUND");
194
- }
195
- }
196
-
197
- export class ValidationError extends AppError {
198
- constructor(message: string, public errors: Record<string, string[]> = {}) {
199
- super(message, 400, "VALIDATION_ERROR");
200
- }
201
- }
202
-
203
- export class UnauthorizedError extends AppError {
204
- constructor(message = "Authentication required") {
205
- super(message, 401, "UNAUTHORIZED");
206
- }
207
- }
208
-
209
- // Express error middleware
210
- app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
211
- if (err instanceof AppError && err.isOperational) {
212
- res.status(err.statusCode).json({
213
- error: { code: err.code, message: err.message },
214
- });
215
- } else {
216
- // Programmer error — log and return generic message
217
- console.error("Unexpected error:", err);
218
- res.status(500).json({
219
- error: { code: "INTERNAL_ERROR", message: "Something went wrong" },
220
- });
221
- }
222
- });
223
- ```
224
-
225
- ---
226
-
227
- ## Async Patterns
228
-
229
- ### Parallel vs Sequential
230
-
231
- ```typescript
232
- // ❌ SEQUENTIAL: Each await blocks the next
233
- const users = await getUsers(); // 200ms
234
- const posts = await getPosts(); // 200ms
235
- const stats = await getStats(); // 200ms
236
- // Total: 600ms
237
-
238
- // PARALLEL: All start simultaneously
239
- const [users, posts, stats] = await Promise.all([
240
- getUsers(), // 200ms
241
- getPosts(), // 200ms (concurrent)
242
- getStats(), // 200ms (concurrent)
243
- ]);
244
- // Total: ~200ms
245
-
246
- // Promise.allSettled — when some can fail
247
- const results = await Promise.allSettled([
248
- fetchCriticalData(),
249
- fetchOptionalData(),
250
- fetchAnalytics(),
251
- ]);
252
-
253
- for (const result of results) {
254
- if (result.status === "fulfilled") {
255
- process(result.value);
256
- } else {
257
- console.error("Failed:", result.reason);
258
- }
259
- }
260
- ```
261
-
262
- ### Retry Pattern
263
-
264
- ```typescript
265
- async function withRetry<T>(
266
- fn: () => Promise<T>,
267
- options: { maxRetries?: number; baseDelay?: number; maxDelay?: number } = {},
268
- ): Promise<T> {
269
- const { maxRetries = 3, baseDelay = 1000, maxDelay = 10000 } = options;
270
-
271
- for (let attempt = 0; attempt <= maxRetries; attempt++) {
272
- try {
273
- return await fn();
274
- } catch (error) {
275
- if (attempt === maxRetries) throw error;
276
-
277
- const delay = Math.min(baseDelay * 2 ** attempt, maxDelay);
278
- const jitter = delay * (0.5 + Math.random() * 0.5);
279
- console.warn(`Attempt ${attempt + 1} failed, retrying in ${jitter}ms`);
280
- await new Promise((resolve) => setTimeout(resolve, jitter));
281
- }
282
- }
283
- throw new Error("Unreachable");
284
- }
285
-
286
- // Usage:
287
- const data = await withRetry(() => fetch("https://api.flaky.com/data"), {
288
- maxRetries: 3,
289
- baseDelay: 500,
290
- });
291
- ```
292
-
293
- ### AbortController (Timeouts & Cancellation)
294
-
295
- ```typescript
296
- async function fetchWithTimeout(url: string, timeoutMs = 5000): Promise<Response> {
297
- const controller = new AbortController();
298
- const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
299
-
300
- try {
301
- const response = await fetch(url, { signal: controller.signal });
302
- return response;
303
- } catch (error) {
304
- if (error instanceof DOMException && error.name === "AbortError") {
305
- throw new Error(`Request to ${url} timed out after ${timeoutMs}ms`);
306
- }
307
- throw error;
308
- } finally {
309
- clearTimeout(timeoutId);
310
- }
311
- }
312
- ```
313
-
314
- ---
315
-
316
- ## Streaming
317
-
318
- ```typescript
319
- import { Readable, Transform, pipeline } from "node:stream/promises";
320
- import { createReadStream, createWriteStream } from "node:fs";
321
- import { createGzip } from "node:zlib";
322
-
323
- // Stream large file processing (no memory issues)
324
- async function processLargeCSV(inputPath: string, outputPath: string) {
325
- const transform = new Transform({
326
- transform(chunk, encoding, callback) {
327
- const processed = chunk.toString().toUpperCase();
328
- callback(null, processed);
329
- },
330
- });
331
-
332
- await pipeline(
333
- createReadStream(inputPath),
334
- transform,
335
- createGzip(),
336
- createWriteStream(outputPath),
337
- );
338
- }
339
-
340
- // Streaming HTTP response
341
- app.get("/export", async (req, res) => {
342
- res.setHeader("Content-Type", "text/csv");
343
- res.setHeader("Content-Disposition", "attachment; filename=export.csv");
344
-
345
- const cursor = db.collection("users").find().stream();
346
- cursor.on("data", (user) => {
347
- res.write(`${user.id},${user.name},${user.email}\n`);
348
- });
349
- cursor.on("end", () => res.end());
350
- cursor.on("error", (err) => {
351
- console.error(err);
352
- res.status(500).end();
353
- });
354
- });
355
-
356
- // ❌ HALLUCINATION TRAP: Use stream/promises (not callbacks)
357
- // ❌ const { pipeline } = require("stream"); ← callback-based
358
- // ✅ import { pipeline } from "node:stream/promises"; ← async/await
359
- ```
360
-
361
- ---
362
-
363
- ## Environment & Config
364
-
365
- ```typescript
366
- // config.ts centralized, validated configuration
367
- import { z } from "zod";
368
-
369
- const envSchema = z.object({
370
- NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
371
- PORT: z.coerce.number().default(3000),
372
- DATABASE_URL: z.string().url(),
373
- REDIS_URL: z.string().url().optional(),
374
- JWT_SECRET: z.string().min(32),
375
- CORS_ORIGIN: z.string().default("http://localhost:5173"),
376
- LOG_LEVEL: z.enum(["debug", "info", "warn", "error"]).default("info"),
377
- });
378
-
379
- export const config = envSchema.parse(process.env);
380
-
381
- // ❌ HALLUCINATION TRAP: Validate env vars at startup — fail FAST
382
- // ❌ process.env.DATABASE_URL!crashes at runtime, not startup
383
- // ✅ Validate with Zod on app init — crash immediately with clear error
384
-
385
- // ❌ HALLUCINATION TRAP: Never hardcode secrets
386
- // ❌ const JWT_SECRET = "my-secret-key"; ← in source code
387
- // ✅ const JWT_SECRET = process.env.JWT_SECRET; ← from environment
388
- ```
389
-
390
- ---
391
-
392
- ## Security Hardening
393
-
394
- ```typescript
395
- import helmet from "helmet";
396
- import rateLimit from "express-rate-limit";
397
-
398
- // Security headers
399
- app.use(helmet());
400
-
401
- // Rate limiting
402
- app.use("/api/", rateLimit({
403
- windowMs: 15 * 60 * 1000, // 15 minutes
404
- max: 100, // 100 requests per window
405
- standardHeaders: true,
406
- legacyHeaders: false,
407
- message: { error: "Too many requests, try again later" },
408
- }));
409
-
410
- // Auth rate limiting (stricter)
411
- app.use("/api/auth/", rateLimit({
412
- windowMs: 15 * 60 * 1000,
413
- max: 5, // only 5 login attempts per 15 min
414
- }));
415
-
416
- // Input validation (ALWAYS validate)
417
- app.post("/api/users", async (req, res, next) => {
418
- try {
419
- const data = CreateUserSchema.parse(req.body); // Zod validates
420
- const user = await createUser(data);
421
- res.status(201).json(user);
422
- } catch (error) {
423
- next(error);
424
- }
425
- });
426
-
427
- // SQL injection prevention (covered by parameterized queries)
428
- // db.query(`SELECT * FROM users WHERE id = ${req.params.id}`);
429
- // ✅ db.query("SELECT * FROM users WHERE id = $1", [req.params.id]);
430
-
431
- // Path traversal prevention
432
- import { resolve, normalize } from "node:path";
433
-
434
- function safePath(userInput: string, baseDir: string): string {
435
- const resolved = resolve(baseDir, normalize(userInput));
436
- if (!resolved.startsWith(baseDir)) {
437
- throw new Error("Path traversal detected");
438
- }
439
- return resolved;
440
- }
441
- ```
442
-
443
- ---
444
-
445
- ## Process Management
446
-
447
- ### Graceful Shutdown
448
-
449
- ```typescript
450
- async function gracefulShutdown(signal: string) {
451
- console.log(`\n${signal} received — shutting down gracefully`);
452
-
453
- // Stop accepting new connections
454
- server.close();
455
-
456
- // Close database connections
457
- await db.end();
458
-
459
- // Close Redis
460
- await redis.quit();
461
-
462
- // Allow in-flight requests 10s to complete
463
- setTimeout(() => {
464
- console.error("Forceful shutdown after timeout");
465
- process.exit(1);
466
- }, 10000);
467
-
468
- process.exit(0);
469
- }
470
-
471
- process.on("SIGTERM", () => gracefulShutdown("SIGTERM"));
472
- process.on("SIGINT", () => gracefulShutdown("SIGINT"));
473
- ```
474
-
475
- ### Worker Threads (CPU-Bound)
476
-
477
- ```typescript
478
- import { Worker, isMainThread, parentPort, workerData } from "node:worker_threads";
479
-
480
- if (isMainThread) {
481
- // Main thread — offload CPU work
482
- function runWorker(data: unknown): Promise<unknown> {
483
- return new Promise((resolve, reject) => {
484
- const worker = new Worker(new URL(import.meta.url), { workerData: data });
485
- worker.on("message", resolve);
486
- worker.on("error", reject);
487
- });
488
- }
489
-
490
- const result = await runWorker({ input: largeDataSet });
491
- } else {
492
- // Worker thread — CPU-intensive work
493
- const result = heavyComputation(workerData.input);
494
- parentPort?.postMessage(result);
495
- }
496
-
497
- // ❌ HALLUCINATION TRAP: Worker threads are for CPU-bound tasks
498
- // For I/O-bound tasks (network, file), use async/await — NOT workers
499
- // Workers have overhead (serialization, memory) — don't overuse
500
- ```
501
-
502
- ---
503
-
504
- ## Output Format
505
-
506
- ```
507
- ━━━ Node.js Report ━━━━━━━━━━━━━━━━━━━━━━━━
508
- Skill: Node.js Best Practices
509
- Node Ver: 22+
510
- Scope: [N files · N endpoints]
511
- ─────────────────────────────────────────────────
512
- ✅ Passed: [checks that passed, or "All clean"]
513
- ⚠️ Warnings: [non-blocking issues, or "None"]
514
- ❌ Blocked: [blocking issues requiring fix, or "None"]
515
- ─────────────────────────────────────────────────
516
- VBC status: PENDING → VERIFIED
517
- Evidence: [test output / server start / build success]
518
- ```
519
-
520
- ---
521
-
522
- ## 🤖 LLM-Specific Traps
523
-
524
- 1. **`require()` in ESM:** Never use `require()` in `"type": "module"` projects. Use `import`.
525
- 2. **Missing `node:` Prefix:** Always use `node:fs`, `node:path`, `node:http`, etc. Bare imports are ambiguous.
526
- 3. **Callback-Based APIs:** Use `node:fs/promises`, `node:stream/promises`. Callback APIs are legacy.
527
- 4. **Continuing After `uncaughtException`:** Process MUST exit after uncaughtException. State is corrupted.
528
- 5. **`process.env` Without Validation:** Environment variables are `string | undefined`. Always validate at startup with Zod.
529
- 6. **Hardcoded Secrets:** JWT secrets, API keys, and DB URLs must come from environment, never source code.
530
- 7. **`express()` Without `helmet()`:** Every Express app needs security headers. `helmet()` is non-negotiable.
531
- 8. **SQL String Interpolation:** Never use template literals for SQL. Use parameterized queries.
532
- 9. **Worker Threads for I/O:** Workers are for CPU-bound work. I/O-bound work uses async/await natively.
533
- 10. **Missing Graceful Shutdown:** Servers MUST handle SIGTERM/SIGINT for clean container/PaaS shutdown.
534
-
535
- ---
536
-
537
- ## 🏛️ Tribunal Integration
538
-
539
- **Slash command: `/tribunal-backend`**
540
-
541
- ### ✅ Pre-Flight Self-Audit
542
-
543
- ```
544
- ✅ Did I use ESM imports with node: prefix?
545
- ✅ Did I validate all environment variables at startup?
546
- ✅ Are secrets in environment variables (not hardcoded)?
547
- ✅ Did I handle unhandledRejection and uncaughtException?
548
- ✅ Did I implement graceful shutdown (SIGTERM/SIGINT)?
549
- ✅ Did I use parameterized queries (not string interpolation)?
550
- ✅ Did I add rate limiting and security headers?
551
- ✅ Did I validate all request input with Zod?
552
- ✅ Are async errors properly caught and propagated?
553
- ✅ Did I use streams for large data (not loading all into memory)?
554
- ```
555
-
556
- ### 🛑 VBC Protocol
557
-
558
- - ❌ **Forbidden:** Assuming a server "works" because it starts without errors.
559
- - ✅ **Required:** Provide test output, health check response, or build success evidence.
1
+ ---
2
+ name: nodejs-best-practices
3
+ description: Node.js 22+ production mastery. ES Modules, async patterns, Express/Fastify/Hono, middleware architecture, error handling, streaming, worker threads, environment config, security hardening, process management, and deployment patterns. Use when building Node.js servers, APIs, CLI tools, or any server-side JavaScript.
4
+ allowed-tools: Read, Write, Edit, Glob, Grep
5
+ version: 2.0.0
6
+ last-updated: 2026-04-01
7
+ applies-to-model: gemini-2.5-pro, claude-3-7-sonnet
8
+ ---
9
+
10
+ # Node.js Best Practices — Node 22+ Production Mastery
11
+
12
+ ---
13
+
14
+ ## ES Modules (Mandatory)
15
+
16
+ ```json
17
+ // package.json — ALWAYS set type to module
18
+ {
19
+ "type": "module",
20
+ "engines": { "node": ">=22" }
21
+ }
22
+ ```
23
+
24
+ ```typescript
25
+ // ✅ ESM imports (modern Node.js)
26
+ import { readFile, writeFile } from "node:fs/promises";
27
+ import { join, resolve } from "node:path";
28
+ import { createServer } from "node:http";
29
+ import { EventEmitter } from "node:events";
30
+
31
+ // HALLUCINATION TRAP: Use node: protocol prefix for built-in modules
32
+ // import fs from "fs"; ← ambiguous (could be npm package)
33
+ // import fs from "node:fs"; ← explicitly a Node.js built-in
34
+
35
+ // ❌ HALLUCINATION TRAP: Do NOT use require() in ESM projects
36
+ // ❌ const fs = require("fs"); CommonJS (legacy)
37
+ // ✅ import fs from "node:fs/promises"; ← ESM
38
+
39
+ // Dynamic imports (for conditional loading)
40
+ const module = await import("./heavy-module.js");
41
+ ```
42
+
43
+ ---
44
+
45
+ ## Framework Selection
46
+
47
+ ```
48
+ ┌────────────────────────────────────────────────────────────┐
49
+ │ When to Use What │
50
+ ├────────────────────────────────────────────────────────────┤
51
+ │ Express │ Legacy projects, extensive middleware ecosystem│
52
+ │ Fastify │ Performance-critical APIs, schema validation │
53
+ Hono │ Edge/serverless, multi-runtime (Node/Deno/Bun)
54
+ │ tRPC │ Full-stack TypeScript (Next.js + React Query) │
55
+ Raw http Learning, minimal proxies, health checks
56
+ └────────────────────────────────────────────────────────────┘
57
+ ```
58
+
59
+ ### Fastify (Recommended)
60
+
61
+ ```typescript
62
+ import Fastify from "fastify";
63
+ import { z } from "zod";
64
+
65
+ const app = Fastify({
66
+ logger: {
67
+ level: process.env.LOG_LEVEL ?? "info",
68
+ transport: process.env.NODE_ENV === "development"
69
+ ? { target: "pino-pretty" }
70
+ : undefined,
71
+ },
72
+ });
73
+
74
+ // Schema validation with Zod → Fastify schema
75
+ const CreateUserSchema = z.object({
76
+ name: z.string().min(2).max(100),
77
+ email: z.string().email(),
78
+ role: z.enum(["admin", "user"]).default("user"),
79
+ });
80
+
81
+ type CreateUserBody = z.infer<typeof CreateUserSchema>;
82
+
83
+ app.post<{ Body: CreateUserBody }>("/users", {
84
+ schema: {
85
+ body: {
86
+ type: "object",
87
+ required: ["name", "email"],
88
+ properties: {
89
+ name: { type: "string", minLength: 2 },
90
+ email: { type: "string", format: "email" },
91
+ role: { type: "string", enum: ["admin", "user"] },
92
+ },
93
+ },
94
+ },
95
+ }, async (request, reply) => {
96
+ const validated = CreateUserSchema.parse(request.body);
97
+ const user = await createUser(validated);
98
+ return reply.status(201).send(user);
99
+ });
100
+
101
+ // Graceful shutdown
102
+ const start = async () => {
103
+ try {
104
+ await app.listen({ port: 3000, host: "0.0.0.0" });
105
+ } catch (err) {
106
+ app.log.error(err);
107
+ process.exit(1);
108
+ }
109
+ };
110
+
111
+ start();
112
+ ```
113
+
114
+ ### Hono (Edge-First)
115
+
116
+ ```typescript
117
+ import { Hono } from "hono";
118
+ import { cors } from "hono/cors";
119
+ import { logger } from "hono/logger";
120
+ import { zValidator } from "@hono/zod-validator";
121
+ import { z } from "zod";
122
+
123
+ const app = new Hono();
124
+
125
+ app.use("*", logger());
126
+ app.use("*", cors({ origin: "https://myapp.com" }));
127
+
128
+ const createUserSchema = z.object({
129
+ name: z.string().min(2),
130
+ email: z.string().email(),
131
+ });
132
+
133
+ app.post("/users", zValidator("json", createUserSchema), async (c) => {
134
+ const body = c.req.valid("json");
135
+ const user = await createUser(body);
136
+ return c.json(user, 201);
137
+ });
138
+
139
+ app.get("/health", (c) => c.json({ status: "ok" }));
140
+
141
+ export default app; // works in Node, Deno, Bun, Cloudflare Workers
142
+ ```
143
+
144
+ ---
145
+
146
+ ## Error Handling
147
+
148
+ ### Global Error Handlers
149
+
150
+ ```typescript
151
+ // ✅ MANDATORY: Handle unhandled rejections and exceptions
152
+ process.on("unhandledRejection", (reason, promise) => {
153
+ console.error("Unhandled Rejection at:", promise, "reason:", reason);
154
+ // Log to error tracking service (Sentry, etc.)
155
+ // Gracefully shutdown
156
+ process.exit(1);
157
+ });
158
+
159
+ process.on("uncaughtException", (error) => {
160
+ console.error("Uncaught Exception:", error);
161
+ // Log to error tracking service
162
+ process.exit(1); // MUST exit — state is corrupted
163
+ });
164
+
165
+ // HALLUCINATION TRAP: After uncaughtException, the process MUST exit
166
+ // The process is in an undefined state — continuing is dangerous
167
+ // ❌ process.on("uncaughtException", (err) => { console.log(err); }); // continues running
168
+ // ✅ process.on("uncaughtException", (err) => { log(err); process.exit(1); });
169
+ ```
170
+
171
+ ### Application Error Classes
172
+
173
+ ```typescript
174
+ export class AppError extends Error {
175
+ constructor(
176
+ message: string,
177
+ public statusCode: number = 500,
178
+ public code: string = "INTERNAL_ERROR",
179
+ public isOperational: boolean = true,
180
+ ) {
181
+ super(message);
182
+ this.name = "AppError";
183
+ Error.captureStackTrace(this, this.constructor);
184
+ }
185
+ }
186
+
187
+ export class NotFoundError extends AppError {
188
+ constructor(resource: string, id: string) {
189
+ super(`${resource} '${id}' not found`, 404, "NOT_FOUND");
190
+ }
191
+ }
192
+
193
+ export class ValidationError extends AppError {
194
+ constructor(message: string, public errors: Record<string, string[]> = {}) {
195
+ super(message, 400, "VALIDATION_ERROR");
196
+ }
197
+ }
198
+
199
+ export class UnauthorizedError extends AppError {
200
+ constructor(message = "Authentication required") {
201
+ super(message, 401, "UNAUTHORIZED");
202
+ }
203
+ }
204
+
205
+ // Express error middleware
206
+ app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
207
+ if (err instanceof AppError && err.isOperational) {
208
+ res.status(err.statusCode).json({
209
+ error: { code: err.code, message: err.message },
210
+ });
211
+ } else {
212
+ // Programmer error — log and return generic message
213
+ console.error("Unexpected error:", err);
214
+ res.status(500).json({
215
+ error: { code: "INTERNAL_ERROR", message: "Something went wrong" },
216
+ });
217
+ }
218
+ });
219
+ ```
220
+
221
+ ---
222
+
223
+ ## Async Patterns
224
+
225
+ ### Parallel vs Sequential
226
+
227
+ ```typescript
228
+ // ❌ SEQUENTIAL: Each await blocks the next
229
+ const users = await getUsers(); // 200ms
230
+ const posts = await getPosts(); // 200ms
231
+ const stats = await getStats(); // 200ms
232
+ // Total: 600ms
233
+
234
+ // PARALLEL: All start simultaneously
235
+ const [users, posts, stats] = await Promise.all([
236
+ getUsers(), // 200ms
237
+ getPosts(), // 200ms (concurrent)
238
+ getStats(), // 200ms (concurrent)
239
+ ]);
240
+ // Total: ~200ms
241
+
242
+ // Promise.allSettled — when some can fail
243
+ const results = await Promise.allSettled([
244
+ fetchCriticalData(),
245
+ fetchOptionalData(),
246
+ fetchAnalytics(),
247
+ ]);
248
+
249
+ for (const result of results) {
250
+ if (result.status === "fulfilled") {
251
+ process(result.value);
252
+ } else {
253
+ console.error("Failed:", result.reason);
254
+ }
255
+ }
256
+ ```
257
+
258
+ ### Retry Pattern
259
+
260
+ ```typescript
261
+ async function withRetry<T>(
262
+ fn: () => Promise<T>,
263
+ options: { maxRetries?: number; baseDelay?: number; maxDelay?: number } = {},
264
+ ): Promise<T> {
265
+ const { maxRetries = 3, baseDelay = 1000, maxDelay = 10000 } = options;
266
+
267
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
268
+ try {
269
+ return await fn();
270
+ } catch (error) {
271
+ if (attempt === maxRetries) throw error;
272
+
273
+ const delay = Math.min(baseDelay * 2 ** attempt, maxDelay);
274
+ const jitter = delay * (0.5 + Math.random() * 0.5);
275
+ console.warn(`Attempt ${attempt + 1} failed, retrying in ${jitter}ms`);
276
+ await new Promise((resolve) => setTimeout(resolve, jitter));
277
+ }
278
+ }
279
+ throw new Error("Unreachable");
280
+ }
281
+
282
+ // Usage:
283
+ const data = await withRetry(() => fetch("https://api.flaky.com/data"), {
284
+ maxRetries: 3,
285
+ baseDelay: 500,
286
+ });
287
+ ```
288
+
289
+ ### AbortController (Timeouts & Cancellation)
290
+
291
+ ```typescript
292
+ async function fetchWithTimeout(url: string, timeoutMs = 5000): Promise<Response> {
293
+ const controller = new AbortController();
294
+ const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
295
+
296
+ try {
297
+ const response = await fetch(url, { signal: controller.signal });
298
+ return response;
299
+ } catch (error) {
300
+ if (error instanceof DOMException && error.name === "AbortError") {
301
+ throw new Error(`Request to ${url} timed out after ${timeoutMs}ms`);
302
+ }
303
+ throw error;
304
+ } finally {
305
+ clearTimeout(timeoutId);
306
+ }
307
+ }
308
+ ```
309
+
310
+ ---
311
+
312
+ ## Streaming
313
+
314
+ ```typescript
315
+ import { Readable, Transform, pipeline } from "node:stream/promises";
316
+ import { createReadStream, createWriteStream } from "node:fs";
317
+ import { createGzip } from "node:zlib";
318
+
319
+ // Stream large file processing (no memory issues)
320
+ async function processLargeCSV(inputPath: string, outputPath: string) {
321
+ const transform = new Transform({
322
+ transform(chunk, encoding, callback) {
323
+ const processed = chunk.toString().toUpperCase();
324
+ callback(null, processed);
325
+ },
326
+ });
327
+
328
+ await pipeline(
329
+ createReadStream(inputPath),
330
+ transform,
331
+ createGzip(),
332
+ createWriteStream(outputPath),
333
+ );
334
+ }
335
+
336
+ // Streaming HTTP response
337
+ app.get("/export", async (req, res) => {
338
+ res.setHeader("Content-Type", "text/csv");
339
+ res.setHeader("Content-Disposition", "attachment; filename=export.csv");
340
+
341
+ const cursor = db.collection("users").find().stream();
342
+ cursor.on("data", (user) => {
343
+ res.write(`${user.id},${user.name},${user.email}\n`);
344
+ });
345
+ cursor.on("end", () => res.end());
346
+ cursor.on("error", (err) => {
347
+ console.error(err);
348
+ res.status(500).end();
349
+ });
350
+ });
351
+
352
+ // ❌ HALLUCINATION TRAP: Use stream/promises (not callbacks)
353
+ // ❌ const { pipeline } = require("stream"); ← callback-based
354
+ // ✅ import { pipeline } from "node:stream/promises"; ← async/await
355
+ ```
356
+
357
+ ---
358
+
359
+ ## Environment & Config
360
+
361
+ ```typescript
362
+ // config.ts — centralized, validated configuration
363
+ import { z } from "zod";
364
+
365
+ const envSchema = z.object({
366
+ NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
367
+ PORT: z.coerce.number().default(3000),
368
+ DATABASE_URL: z.string().url(),
369
+ REDIS_URL: z.string().url().optional(),
370
+ JWT_SECRET: z.string().min(32),
371
+ CORS_ORIGIN: z.string().default("http://localhost:5173"),
372
+ LOG_LEVEL: z.enum(["debug", "info", "warn", "error"]).default("info"),
373
+ });
374
+
375
+ export const config = envSchema.parse(process.env);
376
+
377
+ // ❌ HALLUCINATION TRAP: Validate env vars at startup — fail FAST
378
+ // ❌ process.env.DATABASE_URL! ← crashes at runtime, not startup
379
+ // Validate with Zod on app init — crash immediately with clear error
380
+
381
+ // ❌ HALLUCINATION TRAP: Never hardcode secrets
382
+ // ❌ const JWT_SECRET = "my-secret-key";in source code
383
+ // ✅ const JWT_SECRET = process.env.JWT_SECRET; ← from environment
384
+ ```
385
+
386
+ ---
387
+
388
+ ## Security Hardening
389
+
390
+ ```typescript
391
+ import helmet from "helmet";
392
+ import rateLimit from "express-rate-limit";
393
+
394
+ // Security headers
395
+ app.use(helmet());
396
+
397
+ // Rate limiting
398
+ app.use("/api/", rateLimit({
399
+ windowMs: 15 * 60 * 1000, // 15 minutes
400
+ max: 100, // 100 requests per window
401
+ standardHeaders: true,
402
+ legacyHeaders: false,
403
+ message: { error: "Too many requests, try again later" },
404
+ }));
405
+
406
+ // Auth rate limiting (stricter)
407
+ app.use("/api/auth/", rateLimit({
408
+ windowMs: 15 * 60 * 1000,
409
+ max: 5, // only 5 login attempts per 15 min
410
+ }));
411
+
412
+ // Input validation (ALWAYS validate)
413
+ app.post("/api/users", async (req, res, next) => {
414
+ try {
415
+ const data = CreateUserSchema.parse(req.body); // Zod validates
416
+ const user = await createUser(data);
417
+ res.status(201).json(user);
418
+ } catch (error) {
419
+ next(error);
420
+ }
421
+ });
422
+
423
+ // SQL injection prevention (covered by parameterized queries)
424
+ // ❌ db.query(`SELECT * FROM users WHERE id = ${req.params.id}`);
425
+ // ✅ db.query("SELECT * FROM users WHERE id = $1", [req.params.id]);
426
+
427
+ // Path traversal prevention
428
+ import { resolve, normalize } from "node:path";
429
+
430
+ function safePath(userInput: string, baseDir: string): string {
431
+ const resolved = resolve(baseDir, normalize(userInput));
432
+ if (!resolved.startsWith(baseDir)) {
433
+ throw new Error("Path traversal detected");
434
+ }
435
+ return resolved;
436
+ }
437
+ ```
438
+
439
+ ---
440
+
441
+ ## Process Management
442
+
443
+ ### Graceful Shutdown
444
+
445
+ ```typescript
446
+ async function gracefulShutdown(signal: string) {
447
+ console.log(`\n${signal} received — shutting down gracefully`);
448
+
449
+ // Stop accepting new connections
450
+ server.close();
451
+
452
+ // Close database connections
453
+ await db.end();
454
+
455
+ // Close Redis
456
+ await redis.quit();
457
+
458
+ // Allow in-flight requests 10s to complete
459
+ setTimeout(() => {
460
+ console.error("Forceful shutdown after timeout");
461
+ process.exit(1);
462
+ }, 10000);
463
+
464
+ process.exit(0);
465
+ }
466
+
467
+ process.on("SIGTERM", () => gracefulShutdown("SIGTERM"));
468
+ process.on("SIGINT", () => gracefulShutdown("SIGINT"));
469
+ ```
470
+
471
+ ### Worker Threads (CPU-Bound)
472
+
473
+ ```typescript
474
+ import { Worker, isMainThread, parentPort, workerData } from "node:worker_threads";
475
+
476
+ if (isMainThread) {
477
+ // Main thread — offload CPU work
478
+ function runWorker(data: unknown): Promise<unknown> {
479
+ return new Promise((resolve, reject) => {
480
+ const worker = new Worker(new URL(import.meta.url), { workerData: data });
481
+ worker.on("message", resolve);
482
+ worker.on("error", reject);
483
+ });
484
+ }
485
+
486
+ const result = await runWorker({ input: largeDataSet });
487
+ } else {
488
+ // Worker thread — CPU-intensive work
489
+ const result = heavyComputation(workerData.input);
490
+ parentPort?.postMessage(result);
491
+ }
492
+
493
+ // HALLUCINATION TRAP: Worker threads are for CPU-bound tasks
494
+ // For I/O-bound tasks (network, file), use async/await — NOT workers
495
+ // Workers have overhead (serialization, memory) — don't overuse
496
+ ```
497
+
498
+ ---