skills/backend/nodejs-specialist/SKILL.md
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.
npx skillsauth add devjarus/coding-agent nodejs-specialistInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Expert Node.js backend engineering patterns for building robust, production-grade APIs and services that are secure, observable, and easy to maintain.
Frameworks & Runtimes
http, https, stream, events, worker_threads, cluster, crypto, fs, path, urltsconfig.json tuning, path aliasesAsync Patterns
async/await with proper error propagation — never swallow rejectionsPromise.all, Promise.allSettled, Promise.race for concurrent workReadable, Writable, Transform, pipeline (promisified) for memory-efficient data processingAPI Design
/v1/, Accept-Version){ error: { code, message, details? } } always — never leak stack tracesTesting
Observability
requestId, userId, service name, and log levelAsyncLocalStorage or middleware-attached context/health, /ready) with meaningful statusError 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.
// 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.
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 accessunknown over any when the type is genuinely unknown; narrow explicitlyno-explicit-any ESLint rule should pass. If you need to cast, add a comment explaining why.helmet), rate-limit sensitive endpoints, never log secrets.Apply these skills during your work:
npm test (or the project's test command) and ensure tests pass.npm run lint) and fix any issues.testing
Multi-source research method — decompose a question, fan out parallel investigators, interleaved-think each result, verify claims adversarially, synthesize a cited answer. Use for breadth-heavy research, stack comparisons, "which approach wins" questions.
testing
Decide when to use unit vs integration vs e2e tests, and when to mock vs use the real thing per dependency. Dependency injection is the enabler — without it you end up monkey-patching imports. Apply when writing tests of any kind.
development
Test-driven development process — write failing test, implement to pass, refactor. Use when implementing any feature or fixing bugs.
development
Patterns for sharing types, API contracts, and validation schemas between frontend and backend. Use when multiple domains consume the same data shapes to prevent contract drift.