node-asynclisted
Install: claude install-skill AllThingsSmitty/agent-skills
# Node.js Async Patterns
Node.js runs on a single thread. Everything async works because the event loop defers I/O — but that model breaks the moment you block the thread or mismanage promises. Most Node.js production issues trace back to one of a handful of async mistakes.
## Never block the event loop
The event loop handles every request. If you block it — with a CPU-intensive loop, a synchronous file read, or heavy JSON parsing — every in-flight request stalls until you're done.
```ts
// Bad: blocks the event loop for every caller
app.get("/report", (req, res) => {
const result = fs.readFileSync("large-file.csv"); // synchronous — blocks
res.send(process(result));
});
// Good: yields to the event loop
app.get("/report", async (req, res) => {
const result = await fs.promises.readFile("large-file.csv");
res.send(process(result));
});
```
**CPU-bound work** (parsing, hashing, compression) belongs in a Worker Thread, not the event loop. Offload it:
```ts
import { Worker } from "worker_threads";
function runInWorker(data: unknown): Promise<unknown> {
return new Promise((resolve, reject) => {
const worker = new Worker("./worker.js", { workerData: data });
worker.on("message", resolve);
worker.on("error", reject);
});
}
```
## Handle every rejected promise
In modern Node.js (v15+), an unhandled promise rejection crashes the process. In older versions it silently swallows the error — often worse.
```ts
// Bad: rejection is swallowed if sendEmail