Node.js development principles and decision-making. Framework selection, async patterns, security, and architecture. Teaches thinking, not copying.
Add this skill
npx mdskills install sickn33/nodejs-best-practicesTeaches principled Node.js decision-making with decision trees, comparison tables, and context-aware guidance.
1---2name: nodejs-best-practices3description: Node.js development principles and decision-making. Framework selection, async patterns, security, and architecture. Teaches thinking, not copying.4allowed-tools: Read, Write, Edit, Glob, Grep5---67# Node.js Best Practices89> Principles and decision-making for Node.js development in 2025.10> **Learn to THINK, not memorize code patterns.**1112---1314## ⚠️ How to Use This Skill1516This skill teaches **decision-making principles**, not fixed code to copy.1718- ASK user for preferences when unclear19- Choose framework/pattern based on CONTEXT20- Don't default to same solution every time2122---2324## 1. Framework Selection (2025)2526### Decision Tree2728```29What are you building?30│31├── Edge/Serverless (Cloudflare, Vercel)32│ └── Hono (zero-dependency, ultra-fast cold starts)33│34├── High Performance API35│ └── Fastify (2-3x faster than Express)36│37├── Enterprise/Team familiarity38│ └── NestJS (structured, DI, decorators)39│40├── Legacy/Stable/Maximum ecosystem41│ └── Express (mature, most middleware)42│43└── Full-stack with frontend44 └── Next.js API Routes or tRPC45```4647### Comparison Principles4849| Factor | Hono | Fastify | Express |50|--------|------|---------|---------|51| **Best for** | Edge, serverless | Performance | Legacy, learning |52| **Cold start** | Fastest | Fast | Moderate |53| **Ecosystem** | Growing | Good | Largest |54| **TypeScript** | Native | Excellent | Good |55| **Learning curve** | Low | Medium | Low |5657### Selection Questions to Ask:581. What's the deployment target?592. Is cold start time critical?603. Does team have existing experience?614. Is there legacy code to maintain?6263---6465## 2. Runtime Considerations (2025)6667### Native TypeScript6869```70Node.js 22+: --experimental-strip-types71├── Run .ts files directly72├── No build step needed for simple projects73└── Consider for: scripts, simple APIs74```7576### Module System Decision7778```79ESM (import/export)80├── Modern standard81├── Better tree-shaking82├── Async module loading83└── Use for: new projects8485CommonJS (require)86├── Legacy compatibility87├── More npm packages support88└── Use for: existing codebases, some edge cases89```9091### Runtime Selection9293| Runtime | Best For |94|---------|----------|95| **Node.js** | General purpose, largest ecosystem |96| **Bun** | Performance, built-in bundler |97| **Deno** | Security-first, built-in TypeScript |9899---100101## 3. Architecture Principles102103### Layered Structure Concept104105```106Request Flow:107│108├── Controller/Route Layer109│ ├── Handles HTTP specifics110│ ├── Input validation at boundary111│ └── Calls service layer112│113├── Service Layer114│ ├── Business logic115│ ├── Framework-agnostic116│ └── Calls repository layer117│118└── Repository Layer119 ├── Data access only120 ├── Database queries121 └── ORM interactions122```123124### Why This Matters:125- **Testability**: Mock layers independently126- **Flexibility**: Swap database without touching business logic127- **Clarity**: Each layer has single responsibility128129### When to Simplify:130- Small scripts → Single file OK131- Prototypes → Less structure acceptable132- Always ask: "Will this grow?"133134---135136## 4. Error Handling Principles137138### Centralized Error Handling139140```141Pattern:142├── Create custom error classes143├── Throw from any layer144├── Catch at top level (middleware)145└── Format consistent response146```147148### Error Response Philosophy149150```151Client gets:152├── Appropriate HTTP status153├── Error code for programmatic handling154├── User-friendly message155└── NO internal details (security!)156157Logs get:158├── Full stack trace159├── Request context160├── User ID (if applicable)161└── Timestamp162```163164### Status Code Selection165166| Situation | Status | When |167|-----------|--------|------|168| Bad input | 400 | Client sent invalid data |169| No auth | 401 | Missing or invalid credentials |170| No permission | 403 | Valid auth, but not allowed |171| Not found | 404 | Resource doesn't exist |172| Conflict | 409 | Duplicate or state conflict |173| Validation | 422 | Schema valid but business rules fail |174| Server error | 500 | Our fault, log everything |175176---177178## 5. Async Patterns Principles179180### When to Use Each181182| Pattern | Use When |183|---------|----------|184| `async/await` | Sequential async operations |185| `Promise.all` | Parallel independent operations |186| `Promise.allSettled` | Parallel where some can fail |187| `Promise.race` | Timeout or first response wins |188189### Event Loop Awareness190191```192I/O-bound (async helps):193├── Database queries194├── HTTP requests195├── File system196└── Network operations197198CPU-bound (async doesn't help):199├── Crypto operations200├── Image processing201├── Complex calculations202└── → Use worker threads or offload203```204205### Avoiding Event Loop Blocking206207- Never use sync methods in production (fs.readFileSync, etc.)208- Offload CPU-intensive work209- Use streaming for large data210211---212213## 6. Validation Principles214215### Validate at Boundaries216217```218Where to validate:219├── API entry point (request body/params)220├── Before database operations221├── External data (API responses, file uploads)222└── Environment variables (startup)223```224225### Validation Library Selection226227| Library | Best For |228|---------|----------|229| **Zod** | TypeScript first, inference |230| **Valibot** | Smaller bundle (tree-shakeable) |231| **ArkType** | Performance critical |232| **Yup** | Existing React Form usage |233234### Validation Philosophy235236- Fail fast: Validate early237- Be specific: Clear error messages238- Don't trust: Even "internal" data239240---241242## 7. Security Principles243244### Security Checklist (Not Code)245246- [ ] **Input validation**: All inputs validated247- [ ] **Parameterized queries**: No string concatenation for SQL248- [ ] **Password hashing**: bcrypt or argon2249- [ ] **JWT verification**: Always verify signature and expiry250- [ ] **Rate limiting**: Protect from abuse251- [ ] **Security headers**: Helmet.js or equivalent252- [ ] **HTTPS**: Everywhere in production253- [ ] **CORS**: Properly configured254- [ ] **Secrets**: Environment variables only255- [ ] **Dependencies**: Regularly audited256257### Security Mindset258259```260Trust nothing:261├── Query params → validate262├── Request body → validate263├── Headers → verify264├── Cookies → validate265├── File uploads → scan266└── External APIs → validate response267```268269---270271## 8. Testing Principles272273### Test Strategy Selection274275| Type | Purpose | Tools |276|------|---------|-------|277| **Unit** | Business logic | node:test, Vitest |278| **Integration** | API endpoints | Supertest |279| **E2E** | Full flows | Playwright |280281### What to Test (Priorities)2822831. **Critical paths**: Auth, payments, core business2842. **Edge cases**: Empty inputs, boundaries2853. **Error handling**: What happens when things fail?2864. **Not worth testing**: Framework code, trivial getters287288### Built-in Test Runner (Node.js 22+)289290```291node --test src/**/*.test.ts292├── No external dependency293├── Good coverage reporting294└── Watch mode available295```296297---298299## 10. Anti-Patterns to Avoid300301### ❌ DON'T:302- Use Express for new edge projects (use Hono)303- Use sync methods in production code304- Put business logic in controllers305- Skip input validation306- Hardcode secrets307- Trust external data without validation308- Block event loop with CPU work309310### ✅ DO:311- Choose framework based on context312- Ask user for preferences when unclear313- Use layered architecture for growing projects314- Validate all inputs315- Use environment variables for secrets316- Profile before optimizing317318---319320## 11. Decision Checklist321322Before implementing:323324- [ ] **Asked user about stack preference?**325- [ ] **Chosen framework for THIS context?** (not just default)326- [ ] **Considered deployment target?**327- [ ] **Planned error handling strategy?**328- [ ] **Identified validation points?**329- [ ] **Considered security requirements?**330331---332333> **Remember**: Node.js best practices are about decision-making, not memorizing patterns. Every project deserves fresh consideration based on its requirements.334
Full transparency — inspect the skill content before installing.