Node.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.
Applies Node.js runtime conventions for server code, CLI tools, modules, streams, and package configuration.
npx claudepluginhub xobotyi/cc-foundryThis skill inherits all available tools. When active, it can use any tool Claude has access to.
references/errors.mdreferences/event-loop.mdreferences/modules.mdreferences/security.mdreferences/streams.mdRespect the event loop. Every blocking operation is a scalability bug.
Node.js rewards async-first, stream-oriented code. If your Node.js code fights the event loop, it's wrong.
| Topic | Reference | Contents |
|---|---|---|
| Module system | references/modules.md | ESM/CJS comparison tables, file extension rules, conditional exports patterns |
| Event loop | references/event-loop.md | Phase order, execution priority, blocking operations table, worker pool |
| Streams | references/streams.md | Stream types table, pipeline patterns, backpressure details |
| Error handling | references/errors.md | Error categories table, global handlers, centralized error handling |
| Security | references/security.md | Supply chain threats table, HTTP security headers, process hardening |
"type": "module" in package.json. Use .mjs/.cjs only when
mixing module systems within one package.node: prefix for all built-in imports: import fs from 'node:fs'. Prevents
package name collision attacks and is unambiguous.process explicitly. import process from 'node:process'. Never rely on
the process global — explicit imports make dependencies visible."exports" in package.json for libraries. Encapsulates internals — only
paths listed in "exports" are importable by consumers.import() for statically-known dependencies.import.meta.dirname/import.meta.filename instead of __dirname/__filename.import.meta.resolve() instead of require.resolve() in ESM."type" explicitly in package.json, even in CJS packages — future-proofs
the package and helps tooling.types > import >
require > default. Always include "default" as fallback."types" first in conditional exports when publishing TypeScript declarations.# imports ("imports" in package.json) for clean internal paths without
../../../. Supports conditional resolution for platform-specific implementations."main" alongside "exports" only for backward compatibility with old Node.js
or bundlers. Never use "main" alone for new packages.with { type: 'json' } attribute.createRequire() from node:module only when you must require() in ESM
(e.g., native addons).require() can load synchronous ESM (no top-level await). For ESM with
top-level await, use dynamic import()."exports" is
defined.File extension rules and ESM vs CJS comparison tables: see references/modules.md.
Node.js uses a single-threaded event loop for JavaScript and a libuv worker pool for expensive I/O and CPU tasks.
readFileSync, execSync,
crypto.pbkdf2Sync, zlib.inflateSync). Sync APIs are acceptable only in CLI scripts,
startup code, or build tools.worker_threads or child processes. For main-thread
CPU work, partition into chunks with setImmediate() between iterations.JSON.parse, JSON.stringify, regex, or iteration =
DoS vector. A 50MB JSON string blocks the loop for ~2 seconds.(a+)*, no overlapping alternations
(a|a)*, no backreferences with repetition. Use safe-regex2, RE2, or indexOf.setImmediate() over recursive process.nextTick(). nextTick starves I/O
if called recursively. Use nextTick only when you must run before any I/O in the
current tick (e.g., emitting events after construction before listeners attach).queueMicrotask() over process.nextTick() for new code — it's
cross-platform and web-standard.setImmediate always fires before setTimeout(fn, 0). Outside
I/O, the order is non-deterministic — do not depend on it.AbortController for cancellable timers and operations.Phase order, execution priority, blocking operations table, and worker pool details:
see references/event-loop.md.
Streams process data incrementally — use them for large files, HTTP bodies, data transformation pipelines, and proxying. Do not use streams when data is already fully in memory.
pipeline() from node:stream/promises for stream composition. Never manual
.pipe() chains — they don't propagate errors or handle cleanup..write() return value; wait for 'drain' event before
continuing. pipeline() handles this automatically.Readable.from() for converting iterables/async iterables to streams.for await (const chunk of stream)) as the simplest way to
consume readable streams. Backpressure is handled automatically.readline with createInterface for line-by-line file processing.highWaterMark defaults to 16 KiB for byte streams, 16 objects for object mode.
It's a hint, not a hard limit.highWaterMark. Enable with
{ objectMode: true }.stream.destroy(new Error('msg')).Readable.from() over class-based
_read() implementation unless you need fine-grained control._transform(chunk, encoding, callback) and optionally
_flush(callback) for end-of-stream processing._write(chunk, encoding, callback) and optionally
_final(callback) for cleanup before 'finish' event.Stream types table and .pipe() pitfalls: see references/streams.md.
async/await with try/catch. No callbacks for new code.return await when returning promises from try blocks — preserves full
stack traces and ensures catch fires for rejections.Error. Custom errors must extend Error, set a code property for
programmatic matching (not message strings, which change), and set name.error.cause for chaining: new Error("context", { cause: originalErr }).
The full chain is visible via util.inspect() and structured loggers.error.code or instanceof, never by message string.process.on('unhandledRejection') and
process.on('uncaughtException'). Log, clean up, exit. Since Node.js 15+, unhandled
rejections crash the process by default.uncaughtException. The process state is unknown — log, cleanup,
exit.'error' events on all EventEmitters and streams. An unhandled 'error'
event crashes the process. pipeline() handles stream errors automatically.process.on('warning') for non-fatal process warnings (deprecations, memory
leaks, experimental features).catch (e) { log(e); throw e } causes
duplicate logging.Error categories table and operational vs programmer error strategies:
see references/errors.md.
SIGTERM/SIGINT: stop accepting connections, wait for
in-flight requests (with timeout), close DB pools, flush logs, then process.exit(0).
Force-exit on timeout.NODE_ENV=production in production. It enables framework optimizations and
disables debug output.npm ci in CI/production. Never npm install — it ignores lockfile mismatches.Content-Length header before reading the body.stream-json, @streamparser/json) for very large
JSON payloads.headersTimeout,
requestTimeout, timeout, keepAliveTimeout, maxRequestsPerSocket.helmet or equivalent): Strict-Transport-Security,
X-Content-Type-Options: nosniff, X-Frame-Options: DENY, Content-Security-Policy..env files — add to .gitignore.crypto.timingSafeEqual() for secret comparison (prevents timing attacks).crypto.scrypt() or crypto.pbkdf2() (async versions) for password hashing.exec() with user-controlled strings. Use
execFile() or spawn() with argument arrays.eval(), new Function(), or dynamic require() with user input.--max-old-space-size to prevent memory exhaustion.Supply chain threats table, dependency auditing, and security checklist:
see references/security.md.
When writing Node.js code:
node:fs/promises over callback-based node:fs.node:stream/promises for pipeline operations.When reviewing Node.js code:
The javascript skill governs language choices; this skill governs Node.js runtime decisions. Activate typescript alongside both when working with TypeScript.
Respect the event loop. When in doubt, make it async.
Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.
Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.
Create beautiful visual art in .png and .pdf documents using design philosophy. You should use this skill when the user asks to create a poster, piece of art, design, or other static piece. Create original visual designs, never copying existing artists' work to avoid copyright violations.