# Nodejs Specialist

> Node.js expertise — patterns for building APIs, middleware, and server-side logic using Express, Fastify, or Node.js built-ins. Covers async patterns, streams, error handling, and TypeScript on the server. Use when this capability is needed.

- Skill: `tomevault-io/nodejs-specialist` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tomevault-io/nodejs-specialist`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomevault-io/nodejs-specialist/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: tomevault-io (https://skillmd.com/u/tomevault-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tomevault-io/nodejs-specialist

---


# Node.js Specialist

Expert Node.js backend engineering patterns for building robust, production-grade APIs and services that are secure, observable, and easy to maintain.

## When to Apply

- Building or modifying Node.js backend services (Express, Fastify, Hono, Koa)
- Implementing async patterns, streams, or event-driven logic in Node.js
- Setting up API validation, error handling, or observability in a Node.js project
- Configuring TypeScript for server-side Node.js

## Core Expertise

**Frameworks & Runtimes**
- Express, Fastify, Hono, Koa — know each framework's idioms, plugin/middleware systems, and performance tradeoffs
- Node.js built-ins: `http`, `https`, `stream`, `events`, `worker_threads`, `cluster`, `crypto`, `fs`, `path`, `url`
- TypeScript on the server: strict mode, declaration files, `tsconfig.json` tuning, path aliases

**Async Patterns**
- `async/await` with proper error propagation — never swallow rejections
- `Promise.all`, `Promise.allSettled`, `Promise.race` for concurrent work
- Streams: `Readable`, `Writable`, `Transform`, `pipeline` (promisified) for memory-efficient data processing
- EventEmitter patterns, backpressure handling, and stream composition

**API Design**
- RESTful resource modeling, versioning strategies (`/v1/`, `Accept-Version`)
- Request validation at the boundary — zod, joi, or class-validator before any business logic runs
- Structured error responses: `{ error: { code, message, details? } }` always — never leak stack traces
- Pagination, filtering, sorting conventions consistent with the project

**Testing**
- Jest or Vitest with supertest for HTTP integration tests
- Unit tests for pure functions and business logic
- Test at the right level — don't mock what you can test directly

**Observability**
- Structured JSON logging (pino, winston) — include `requestId`, `userId`, service name, and log level
- Request ID propagation via `AsyncLocalStorage` or middleware-attached context
- Health check endpoints (`/health`, `/ready`) with meaningful status

## Coding Patterns

**Error Handling**
Always catch async errors. In Express use a centralized error handler; in Fastify use `setErrorHandler`. Never let unhandled promise rejections crash the process silently.

```typescript
// Centralized async wrapper for Express
const asyncHandler = (fn: RequestHandler): RequestHandler =>
  (req, res, next) => Promise.resolve(fn(req, res, next)).catch(next);

// Centralized error handler
app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
  logger.error({ err, requestId: req.id }, 'Unhandled error');
  res.status(statusFromError(err)).json({
    error: { code: err.name, message: err.message }
  });
});
```

**Validation at the Boundary**
Validate and parse incoming data before it touches business logic. Fail fast with a 400 and a clear message.

**Environment Configuration**
All config comes from environment variables. Use a typed config module (e.g., `envalid` or `zod.parse(process.env)`) — never hardcode secrets or URLs.

**Graceful Shutdown**
Handle `SIGTERM` and `SIGINT`: stop accepting new connections, drain in-flight requests, close DB pools, then exit with code 0.

```typescript
process.on('SIGTERM', async () => {
  server.close(async () => {
    await db.end();
    process.exit(0);
  });
});
```

**TypeScript Discipline**
- `strict: true` in tsconfig — no implicit `any`, no unchecked index access
- Type everything: request bodies, response shapes, env vars, DB results
- Use `unknown` over `any` when the type is genuinely unknown; narrow explicitly
- Prefer interfaces for public API shapes, type aliases for unions and utilities

## Rules

1. **NODE-01 (CRITICAL): Follow the project's framework** — check existing code before introducing a new library or pattern. Fit the codebase style.
2. **NODE-02 (CRITICAL): Type everything** — `no-explicit-any` ESLint rule should pass. If you need to cast, add a comment explaining why.
3. **NODE-03 (HIGH): Test at the right level** — integration tests for API routes, unit tests for business logic. Mock only external I/O (DB, HTTP calls).
4. **NODE-04 (HIGH): Secure by default** — validate all inputs, sanitize outputs, set security headers (`helmet`), rate-limit sensitive endpoints, never log secrets.
5. **NODE-05 (MEDIUM): Use Context7 MCP for documentation lookup** — when you need current docs for a library (Express, Fastify, Hono, zod, etc.), resolve the library ID and fetch up-to-date documentation rather than relying on training-data memory.

## Skills

Apply these skills during your work:
- **tdd** — write failing tests before implementation; unit tests for business logic, integration tests for API routes
- **api-design** — follow REST conventions for resource naming, status codes, and response shapes; validate against the spec's API contract
- **error-handling** — apply boundary patterns; use a centralized error handler, never leak stack traces, always return structured error responses
- **config-management** — use a single typed config module (CFG-01); read all values from environment variables, never hardcode secrets or URLs
- **security-checklist** — apply input validation at the boundary, enforce auth/authz on all protected routes, set security headers, rate-limit sensitive endpoints
- **integration-testing** — use API emulation or test doubles for external services; run integration tests against a test database, not production data

## Workflow

1. Read existing code to understand the framework, patterns, and conventions in use.
2. Use Context7 MCP to fetch current docs for any library you are working with.
3. Write or edit code following the patterns above.
4. Run `npm test` (or the project's test command) and ensure tests pass.
5. Run the linter (`npm run lint`) and fix any issues.
6. Confirm the server starts cleanly and health checks pass.

---
> Source: [devjarus/coding-agent](https://github.com/devjarus/coding-agent) — distributed by [TomeVault](https://tomevault.io).
<!-- tomevault:4.0:skill_md:2026-06-15 -->

