--- name: javascript-ops description: "JavaScript and Node.js patterns, async programming, modules, runtime internals, and modern ES2024+ features. Use for: javascript, js, node, nodejs, esm, commonjs, promise, async await, event loop, v8, npm, es6, es2024, worker threads, streams, event emitter, prototype, closure." allowed-tools: "Read Write Bash" related-skills: [typescript-ops, react-ops, vue-ops, testing-ops] --- # JavaScript Operations Comprehensive reference for modern JavaScript and Node.js — async patterns, module systems, runtime internals, and ES2022-2025 features. --- ## Async Decision Tree ``` What are you doing asynchronously? │ ├─ Simple one-off operation (DB query, HTTP call) │ └─ async/await with try/catch ✓ default choice │ ├─ Multiple independent operations │ ├─ All must succeed → Promise.all([a(), b(), c()]) │ ├─ Don't care about failures → Promise.allSettled([...]) │ └─ First one wins → Promise.race([...]) or Promise.any([...]) │ ├─ Need external resolve/reject control (deferred) │ └─ Promise.withResolvers() (ES2024) │ ├─ Processing a sequence of async values │ ├─ Known array → for...of with await inside loop │ └─ Unknown/infinite sequence → async generator + for await...of │ ├─ Large data / backpressure concerns │ └─ Streams (ReadableStream / node:stream) │ ├─ Transform data in flight → TransformStream / Transform │ └─ Pipe chain → stream.pipeline() (Node) / pipeThrough() (Web) │ ├─ CPU-intensive work (would block event loop) │ ├─ Short burst → offload with setTimeout(fn, 0) to yield │ └─ Real work → Worker (browser) / worker_threads (Node) │ └─ Shared memory needed → SharedArrayBuffer + Atomics │ └─ Legacy code uses callbacks └─ Wrap with util.promisify() (Node) or new Promise() constructor ``` --- ## Module System Decision Tree ``` Which module system should I use? │ ├─ New project / Node 18+ │ └─ ESM (set "type": "module" in package.json) │ ├─ import / export syntax │ ├─ Top-level await supported │ └─ Better tree-shaking with bundlers │ ├─ Publishing a library │ ├─ ESM-only → simplest, but breaks older CJS consumers │ ├─ CJS-only → safe but no tree-shaking │ └─ Dual package (recommended) → "exports" field with conditions │ ├─ "import": "./dist/index.mjs" │ └─ "require": "./dist/index.cjs" │ ├─ Existing CJS project, want ESM │ ├─ Per-file migration → rename to .mjs, update require → import │ ├─ Whole-project → add "type": "module", rename .cjs exceptions │ └─ Keep CJS, add ESM wrapper → create thin .mjs re-export layer │ ├─ Browser (no bundler) │ └─ Native ESM —