npx skills add ...
npx skills add davila7/claude-code-templates --skill nodejs-best-practices
npx skills add davila7/claude-code-templates --skill nodejs-best-practices
Node.js development principles and decision-making. Framework selection, async patterns, security, and architecture. Teaches thinking, not copying.
Principles and decision-making for Node.js development in 2025. Learn to THINK, not memorize code patterns.
This skill teaches decision-making principles, not fixed code to copy.
| Factor | Hono | Fastify | Express |
|---|---|---|---|
| Best for | Edge, serverless | Performance | Legacy, learning |
| Cold start | Fastest | Fast | Moderate |
| Ecosystem | Growing | Good | Largest |
| TypeScript | Native | Excellent | Good |
| Learning curve | Low | Medium | Low |
| Runtime | Best For |
|---|---|
| Node.js | General purpose, largest ecosystem |
| Bun | Performance, built-in bundler |
| Deno | Security-first, built-in TypeScript |
| Situation | Status | When |
|---|---|---|
| Bad input | 400 | Client sent invalid data |
| No auth | 401 | Missing or invalid credentials |
| No permission | 403 | Valid auth, but not allowed |
| Not found | 404 | Resource doesn't exist |
| Conflict | 409 | Duplicate or state conflict |
| Validation | 422 | Schema valid but business rules fail |
| Server error | 500 | Our fault, log everything |
| Pattern | Use When |
|---|---|
async/await | Sequential async operations |
Promise.all | Parallel independent operations |
Promise.allSettled | Parallel where some can fail |
Promise.race | Timeout or first response wins |
| Library | Best For |
|---|---|
| Zod | TypeScript first, inference |
| Valibot | Smaller bundle (tree-shakeable) |
| ArkType | Performance critical |
| Yup | Existing React Form usage |
| Type | Purpose | Tools |
|---|---|---|
| Unit | Business logic | node:test, Vitest |
| Integration | API endpoints | Supertest |
| E2E | Full flows | Playwright |
Before implementing:
Remember: Node.js best practices are about decision-making, not memorizing patterns. Every project deserves fresh consideration based on its requirements.
Request Flow:
│
├── Controller/Route Layer
│ ├── Handles HTTP specifics
│ ├── Input validation at boundary
│ └── Calls service layer
│
├── Service Layer
│ ├── Business logic
│ ├── Framework-agnostic
│ └── Calls repository layer
│
└── Repository Layer
├── Data access only
├── Database queries
└── ORM interactionsPattern:
├── Create custom error classes
├── Throw from any layer
├── Catch at top level (middleware)
└── Format consistent responseClient gets:
├── Appropriate HTTP status
├── Error code for programmatic handling
├── User-friendly message
└── NO internal details (security!)
Logs get:
├── Full stack trace
├── Request context
├── User ID (if applicable)
└── TimestampI/O-bound (async helps):
├── Database queries
├── HTTP requests
├── File system
└── Network operations
CPU-bound (async doesn't help):
├── Crypto operations
├── Image processing
├── Complex calculations
└── → Use worker threads or offloadWhere to validate:
├── API entry point (request body/params)
├── Before database operations
├── External data (API responses, file uploads)
└── Environment variables (startup)Trust nothing:
├── Query params → validate
├── Request body → validate
├── Headers → verify
├── Cookies → validate
├── File uploads → scan
└── External APIs → validate responsenode --test src/**/*.test.ts
├── No external dependency
├── Good coverage reporting
└── Watch mode available