From javascript
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.
npx claudepluginhub xobotyi/cc-foundry --plugin javascriptThis skill uses the workspace's default tool permissions.
**Respect the event loop. Every blocking operation is a scalability bug.**
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
Respect 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.
${CLAUDE_SKILL_DIR}/references/modules.md]: ESM/CJS comparison tables, file extension rules,
conditional exports patterns${CLAUDE_SKILL_DIR}/references/event-loop.md]: Phase order, execution priority, blocking
operations table, worker pool${CLAUDE_SKILL_DIR}/references/streams.md]: Stream types table, pipeline patterns, backpressure
details${CLAUDE_SKILL_DIR}/references/errors.md]: Error categories table, global handlers,
centralized error handling${CLAUDE_SKILL_DIR}/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 ${CLAUDE_SKILL_DIR}/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
${CLAUDE_SKILL_DIR}/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 ${CLAUDE_SKILL_DIR}/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 ${CLAUDE_SKILL_DIR}/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
${CLAUDE_SKILL_DIR}/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.