Node.js Backend
SkillCloud & infraNode.js backend patterns: framework selection, layered architecture, TypeScript, validation, error handling, security, production deployment. Use when building REST APIs, Express/Fastify servers, microservices, or server-side TypeScript.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Node.js Backend skill
What this skill tells your AI
The instructions your AI receives, as published by iliaal/whetstone in distillery/generated-skills/nodejs-backend/SKILL.md and read by ahel’s review.
Framework Selection
| Context | Choose | Why |
|---|---|---|
| Edge/Serverless | Hono | Zero-dep, fastest cold starts |
| Performance API | Fastify | 2-3x faster than Express, built-in schema validation |
| Enterprise/team | NestJS | DI, decorators, structured conventions |
| Legacy/ecosystem | Express | Most middleware, widest adoption |
Ask user: deployment target, cold start needs, team experience, existing codebase.
Architecture
src/
├── routes/ # HTTP: parse request, call service, format response
├── middleware/ # Auth, validation, rate limiting, logging
├── services/ # Business logic (no HTTP types)
├── repositories/ # Data access only (queries, ORM)
├── config/ # Env, DB pool, constants
└── types/ # Shared TypeScript interfaces
- Routes never contain business logic
- Services never import Request/Response
- Repositories never throw HTTP errors
- For scripts/prototypes: single file is fine — ask "will this grow?"
TypeScript Rules
- Use
import type { }for type-only imports — eliminates runtime overhead - Prefer
interfacefor object shapes (2-5x faster type resolution than intersections) - Prefer
unknownoverany— forces explicit narrowing - Use
z.infer<typeof Schema>as single source of truth — never duplicate types and schemas - Minimize
asassertions — use type guards instead - Add explicit return types to exported functions (faster declaration emit)
- Untyped package?
declare module 'pkg' { const v: unknown; export default v; }intypes/ambient.d.ts
Validation
Zod (TypeScript inference) or TypeBox (Fastify native). Validate at boundaries only: request entry, before DB ops, env vars at startup. Use .extend(), .pick(), .omit(), .partial(), .merge() for DRY schemas.
Error Handling
Custom error hierarchy: AppError(message, statusCode, isOperational) → ValidationError(400), NotFoundError(404), UnauthorizedError(401), ForbiddenError(403), ConflictError(409)
Centralized handler middleware:
AppError→ return{ error: message }with statusCode- Unknown → log full stack, return 500 + generic message in production
- Async wrapper:
const asyncHandler = (fn) => (req, res, next) => Promise.resolve(fn(req, res, next)).catch(next);
Codes: 400 bad input | 401 no auth | 403 no permission | 404 missing | 409 conflict | 422 business rule | 429 rate limited | 500 server fault
API Design
- Resources: plural nouns (
/users), max 2 nesting levels (/users/:id/orders) - Methods: GET read | POST create | PUT replace | PATCH partial | DELETE remove
- Versioning: URL path
/api/v1/ - Response:
{ data, pagination?: { page, limit, total, totalPages } } - Errors:
{ error: { code, message, details? } } - Queries:
?page=1&limit=20&status=active&sort=createdAt,desc - Return
Locationheader on 201. Use 204 for successful DELETE with no body.
Async Patterns
| Pattern | Use When |
|---|---|
async/await | Sequential operations |
Promise.all | Parallel independent ops |
Promise.allSettled | Parallel, some may fail |
Promise.race | Timeout or first-wins |
Never readFileSync / sync methods in production. Offload CPU work to worker threads. Stream large payloads.
Discipline
- For non-trivial changes, pause and ask: "is there a more elegant way?" Skip for obvious fixes.
- Simplicity first — every change as simple as possible, impact minimal code
- Only touch what's necessary — avoid introducing unrelated changes
- No hacky workarounds — if a fix feels wrong, step back and implement the clean solution
References
- TypeScript config — tsconfig, ESM, branded types, compiler performance
- Security — JWT, password hashing, rate limiting, OWASP
- Database & production — connection pooling, transactions, Docker, logging
Signals
- GitHub stars
- 33
- Forks
- 3
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
nodejs-backend-2- Source
- github.com/iliaal/whetstone