$npx -y skills add One-Man-Company/Skills-ContextManager --skill nodejs-best-practicesNode.js development principles and decision-making. Framework selection, async patterns, security, and architecture. Teaches thinking, not copying.
| 1 | # Node.js Best Practices |
| 2 | |
| 3 | > Principles and decision-making for Node.js development in 2025. |
| 4 | > **Learn to THINK, not memorize code patterns.** |
| 5 | |
| 6 | --- |
| 7 | |
| 8 | ## ⚠️ How to Use This Skill |
| 9 | |
| 10 | This skill teaches **decision-making principles**, not fixed code to copy. |
| 11 | |
| 12 | - ASK user for preferences when unclear |
| 13 | - Choose framework/pattern based on CONTEXT |
| 14 | - Don't default to same solution every time |
| 15 | |
| 16 | --- |
| 17 | |
| 18 | ## 1. Framework Selection (2025) |
| 19 | |
| 20 | ### Decision Tree |
| 21 | |
| 22 | ``` |
| 23 | What are you building? |
| 24 | │ |
| 25 | ├── Edge/Serverless (Cloudflare, Vercel) |
| 26 | │ └── Hono (zero-dependency, ultra-fast cold starts) |
| 27 | │ |
| 28 | ├── High Performance API |
| 29 | │ └── Fastify (2-3x faster than Express) |
| 30 | │ |
| 31 | ├── Enterprise/Team familiarity |
| 32 | │ └── NestJS (structured, DI, decorators) |
| 33 | │ |
| 34 | ├── Legacy/Stable/Maximum ecosystem |
| 35 | │ └── Express (mature, most middleware) |
| 36 | │ |
| 37 | └── Full-stack with frontend |
| 38 | └── Next.js API Routes or tRPC |
| 39 | ``` |
| 40 | |
| 41 | ### Comparison Principles |
| 42 | |
| 43 | | Factor | Hono | Fastify | Express | |
| 44 | |--------|------|---------|---------| |
| 45 | | **Best for** | Edge, serverless | Performance | Legacy, learning | |
| 46 | | **Cold start** | Fastest | Fast | Moderate | |
| 47 | | **Ecosystem** | Growing | Good | Largest | |
| 48 | | **TypeScript** | Native | Excellent | Good | |
| 49 | | **Learning curve** | Low | Medium | Low | |
| 50 | |
| 51 | ### Selection Questions to Ask: |
| 52 | 1. What's the deployment target? |
| 53 | 2. Is cold start time critical? |
| 54 | 3. Does team have existing experience? |
| 55 | 4. Is there legacy code to maintain? |
| 56 | |
| 57 | --- |
| 58 | |
| 59 | ## 2. Runtime Considerations (2025) |
| 60 | |
| 61 | ### Native TypeScript |
| 62 | |
| 63 | ``` |
| 64 | Node.js 22+: --experimental-strip-types |
| 65 | ├── Run .ts files directly |
| 66 | ├── No build step needed for simple projects |
| 67 | └── Consider for: scripts, simple APIs |
| 68 | ``` |
| 69 | |
| 70 | ### Module System Decision |
| 71 | |
| 72 | ``` |
| 73 | ESM (import/export) |
| 74 | ├── Modern standard |
| 75 | ├── Better tree-shaking |
| 76 | ├── Async module loading |
| 77 | └── Use for: new projects |
| 78 | |
| 79 | CommonJS (require) |
| 80 | ├── Legacy compatibility |
| 81 | ├── More npm packages support |
| 82 | └── Use for: existing codebases, some edge cases |
| 83 | ``` |
| 84 | |
| 85 | ### Runtime Selection |
| 86 | |
| 87 | | Runtime | Best For | |
| 88 | |---------|----------| |
| 89 | | **Node.js** | General purpose, largest ecosystem | |
| 90 | | **Bun** | Performance, built-in bundler | |
| 91 | | **Deno** | Security-first, built-in TypeScript | |
| 92 | |
| 93 | --- |
| 94 | |
| 95 | ## 3. Architecture Principles |
| 96 | |
| 97 | ### Layered Structure Concept |
| 98 | |
| 99 | ``` |
| 100 | Request Flow: |
| 101 | │ |
| 102 | ├── Controller/Route Layer |
| 103 | │ ├── Handles HTTP specifics |
| 104 | │ ├── Input validation at boundary |
| 105 | │ └── Calls service layer |
| 106 | │ |
| 107 | ├── Service Layer |
| 108 | │ ├── Business logic |
| 109 | │ ├── Framework-agnostic |
| 110 | │ └── Calls repository layer |
| 111 | │ |
| 112 | └── Repository Layer |
| 113 | ├── Data access only |
| 114 | ├── Database queries |
| 115 | └── ORM interactions |
| 116 | ``` |
| 117 | |
| 118 | ### Why This Matters: |
| 119 | - **Testability**: Mock layers independently |
| 120 | - **Flexibility**: Swap database without touching business logic |
| 121 | - **Clarity**: Each layer has single responsibility |
| 122 | |
| 123 | ### When to Simplify: |
| 124 | - Small scripts → Single file OK |
| 125 | - Prototypes → Less structure acceptable |
| 126 | - Always ask: "Will this grow?" |
| 127 | |
| 128 | --- |
| 129 | |
| 130 | ## 4. Error Handling Principles |
| 131 | |
| 132 | ### Centralized Error Handling |
| 133 | |
| 134 | ``` |
| 135 | Pattern: |
| 136 | ├── Create custom error classes |
| 137 | ├── Throw from any layer |
| 138 | ├── Catch at top level (middleware) |
| 139 | └── Format consistent response |
| 140 | ``` |
| 141 | |
| 142 | ### Error Response Philosophy |
| 143 | |
| 144 | ``` |
| 145 | Client gets: |
| 146 | ├── Appropriate HTTP status |
| 147 | ├── Error code for programmatic handling |
| 148 | ├── User-friendly message |
| 149 | └── NO internal details (security!) |
| 150 | |
| 151 | Logs get: |
| 152 | ├── Full stack trace |
| 153 | ├── Request context |
| 154 | ├── User ID (if applicable) |
| 155 | └── Timestamp |
| 156 | ``` |
| 157 | |
| 158 | ### Status Code Selection |
| 159 | |
| 160 | | Situation | Status | When | |
| 161 | |-----------|--------|------| |
| 162 | | Bad input | 400 | Client sent invalid data | |
| 163 | | No auth | 401 | Missing or invalid credentials | |
| 164 | | No permission | 403 | Valid auth, but not allowed | |
| 165 | | Not found | 404 | Resource doesn't exist | |
| 166 | | Conflict | 409 | Duplicate or state conflict | |
| 167 | | Validation | 422 | Schema valid but business rules fail | |
| 168 | | Server error | 500 | Our fault, log everything | |
| 169 | |
| 170 | --- |
| 171 | |
| 172 | ## 5. Async Patterns Principles |
| 173 | |
| 174 | ### When to Use Each |
| 175 | |
| 176 | | Pattern | Use When | |
| 177 | |---------|----------| |
| 178 | | `async/await` | Sequential async operations | |
| 179 | | `Promise.all` | Parallel independent operations | |
| 180 | | `Promise.allSettled` | Parallel where some can fail | |
| 181 | | `Promise.race` | Timeout or first response wins | |
| 182 | |
| 183 | ### Event Loop Awareness |
| 184 | |
| 185 | ``` |
| 186 | I/O-bound (async helps): |
| 187 | ├── Database queries |
| 188 | ├── HTTP requests |
| 189 | ├── File system |
| 190 | └── Network operations |
| 191 | |
| 192 | CPU-bound (async doesn't help): |
| 193 | ├── Crypto operations |
| 194 | ├── Image processing |
| 195 | ├── Complex calculations |
| 196 | └── → Use worker threads or offload |
| 197 | ``` |
| 198 | |
| 199 | ### Avoiding Event Loop Blocking |
| 200 | |
| 201 | - Never use sync methods in production (fs.readFileSync, etc.) |
| 202 | - Offload CPU-intensive work |
| 203 | - Use streaming for large data |
| 204 | |
| 205 | --- |
| 206 | |
| 207 | ## 6. Validation Principles |
| 208 | |
| 209 | ### Validate at Boundaries |
| 210 | |
| 211 | ``` |
| 212 | Where to validate: |
| 213 | ├── API entry point (request body/params) |
| 214 | ├── Before database operations |
| 215 | ├── External data (API responses, file uploads) |
| 216 | └── Environment variables ( |