From dh
Reviews Node.js server code for blocking issues like synchronous I/O, stream backpressure, process.exit misuse, security vulnerabilities, dependency hygiene, and event emitter leaks. Auto-loads on package.json + JS files.
How this skill is triggered — by the user, by Claude, or both
Slash command
/dh:code-review-nodejsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Stack-specific rules loaded by `dh:code-reviewer` when `package.json` and `*.js`/`*.mjs` files are detected (without TypeScript).
Stack-specific rules loaded by dh:code-reviewer when package.json and *.js/*.mjs files are detected (without TypeScript).
fs.readFileSync, fs.writeFileSync, execSync, spawnSync in any function called during request handling are blocking findingsfs/promises// WRONG: blocks event loop
app.get("/config", (req, res) => {
const config = fs.readFileSync("./config.json", "utf8");
res.json(JSON.parse(config));
});
// RIGHT: non-blocking
app.get("/config", async (req, res) => {
const config = await fs.promises.readFile("./config.json", "utf8");
res.json(JSON.parse(config));
});
readable.pipe(writable) handles backpressure automatically — prefer it over manual data event listenersdata event listeners must check writable.write() return value and pause the readable when it returns falseprocess.exit() is only acceptable in CLI entrypoints — it is a blocking finding in library code, route handlers, or middlewareprocess.on("uncaughtException") that calls process.exit() without logging the error is a blocking findingeval() is a blocking finding everywhere — no exceptionsnew Function(code) with user-controlled code is a blocking findingexec or spawn are a blocking findingexecFile is required over exec when calling external programs — exec invokes a shell and is vulnerable to injection// WRONG: shell injection vector
exec(`convert ${userInput} output.png`);
// RIGHT: no shell, explicit args
execFile("convert", [userInput, "output.png"]);
* version ranges in package.json are a blocking finding — they produce non-reproducible installs^ ranges are acceptable; ~ is preferred for stricter patch-level pinningpackage-lock.json or yarn.lock must be committed — without a lockfile, versions are not reproducible in CIdevDependencies, not dependencies — they inflate production bundle sizeEventEmitter.on() listeners added in component/connection lifecycle must be removed when that lifecycle endsremoveListener or off() calls are a blocking finding when the emitter outlives the listenerEventEmitter.once() for one-shot listeners to avoid manual cleanupprocess.env.SOME_VAR! without validation is a blocking finding — the app will fail with a confusing error at runtime rather than a clear startup message.env.example file listing all required variables — checked in, never containing real valuesexecFile Over exec// WRONG: shell injection risk
exec(`git log --oneline ${branch}`);
// RIGHT: explicit argument array, no shell
execFile("git", ["log", "--oneline", branch], (err, stdout) => { ... });
// WRONG: missing error handling on EventEmitter
server.on("connection", (socket) => {
socket.on("data", handleData);
// missing: socket.on("end", cleanup) and removeListener
});
// WRONG: unvalidated env at use site
const apiKey = process.env.API_KEY;
fetch(url, { headers: { Authorization: apiKey } }); // null if unset
// RIGHT: validate at startup
if (!process.env.API_KEY) {
console.error("FATAL: API_KEY environment variable is required");
process.exit(1);
}
const apiKey = process.env.API_KEY;
npx claudepluginhub jamie-bitflight/claude_skills --plugin dhNode.js runtime conventions, APIs, and ecosystem patterns. Invoke whenever task involves any interaction with Node.js runtime — server code, CLI tools, scripts, module system, streams, process lifecycle, or package configuration.
Performs security reviews on TypeScript/Node.js apps against OWASP Top 10, checking XSS, injection, CSRF, JWT/OAuth2 flaws, CVEs, secrets exposure. Use for audits before deployment in Express, NestJS, Next.js.
Analyzes codebases for anti-patterns, code smells, and quality issues using ast-grep structural pattern matching in JavaScript, TypeScript, Python, Vue, and React. Use for code reviews and technical debt detection.