Node.js development principles and decision-making. Framework selection, async patterns, security, and architecture. Teaches thinking, not copying.
58
68%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Fix and improve this skill with Tessl
tessl review fix ./.agents/skills/nodejs-best-practices/SKILL.mdPrinciples and decision-making for modern Node.js development. Learn to THINK, not memorize code patterns.
This skill teaches decision-making principles, not fixed code to copy.
What are you building?
│
├── Edge/Serverless (Cloudflare, Vercel)
│ └── Hono (zero-dependency, ultra-fast cold starts)
│
├── High Performance API
│ └── Fastify (~5x req/sec of Express in Fastify's own hello-world benchmark; benchmark your own workload)
│
├── Enterprise/Team familiarity
│ └── NestJS (structured, DI, decorators)
│
├── Legacy/Stable/Maximum ecosystem
│ └── Express (mature, most middleware)
│
└── Full-stack with frontend
└── Next.js API Routes or tRPC| 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 |
Node.js 24+ (Active LTS): type-stripping ON by default
├── Run .ts files directly: node file.ts (no flag, stable since 24.12)
├── Erasable syntax only — enums, runtime namespaces, param properties error out
├── For those, use tsx (--experimental-transform-types was removed in Node 26)
└── Consider for: scripts, simple APIsESM (import/export)
├── Modern standard
├── Better tree-shaking
├── Async module loading
└── Use for: new projects
CommonJS (require)
├── Legacy compatibility
├── More npm packages support
└── Use for: existing codebases, some edge cases| Runtime | Best For |
|---|---|
| Node.js | General purpose, largest ecosystem |
| Bun | Performance, built-in bundler |
| Deno | Security-first, built-in TypeScript |
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)
└── Timestamp| 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 |
I/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)| Library | Best For |
|---|---|
| Zod | TypeScript first, inference |
| Valibot | Smaller bundle (tree-shakeable) |
| ArkType | Performance critical |
| Yup | Existing React Form usage |
Trust nothing:
├── Query params → validate
├── Request body → validate
├── Headers → verify
├── Cookies → validate
├── File uploads → scan
└── External APIs → validate response| Type | Purpose | Tools |
|---|---|---|
| Unit | Business logic | node:test, Vitest |
| Integration | API endpoints | Supertest |
| E2E | Full flows | Playwright |
node --test src/**/*.test.ts
├── No external dependency
├── Good coverage reporting
└── Watch mode availableBefore implementing:
Remember: Node.js best practices are about decision-making, not memorizing patterns. Every project deserves fresh consideration based on its requirements.
04514f0
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.