nodejs
✓Verified·Scanned 2/18/2026
This skill is a Node.js best-practices guide covering event loop, async errors, ESM, environment variables, memory leaks, and streams. It explicitly instructs loading environment files via dotenv.config() and accessing process.env (e.g., PORT), which involves reading .env files.
from clawhub.ai·vcc7d0aa·2.7 KB·0 installs
Scanned from 1.0.0 at cc7d0aa · Transparency log ↗
$ vett add clawhub.ai/ivangdavila/nodejs
Event Loop
fs.readFileSyncblocks entire server — usefs.promises.readFileor callback version- CPU-intensive code blocks — offload to worker threads or child process
setImmediatevsprocess.nextTick— nextTick runs before I/O, setImmediate after- Long-running loops starve I/O — break into chunks with setImmediate
Async Error Handling
- Unhandled promise rejection crashes in Node 15+ — always
.catch()or try/catch with await process.on('unhandledRejection')for global handler — log and exit gracefully- Errors in callbacks need explicit handling — won't propagate to outer try/catch
Promise.allfails fast — one rejection rejects all, usePromise.allSettledif need all results
CommonJS vs ESM
"type": "module"in package.json for ESM — otherwise.mjsextension- ESM:
import x from 'y'— CommonJS:const x = require('y') - No
__dirnamein ESM — useimport.meta.urlwithfileURLToPath - Can't
require()ESM modules — use dynamicimport()which returns Promise exportsis reference tomodule.exports— reassigningexports = xbreaks it
Environment Variables
process.envvalues are always strings —PORT=3000is"3000"not3000- Missing env var is
undefined, not error — check explicitly or use defaults .envfiles needdotenv— not built-in, calldotenv.config()early- Don't commit
.env— use.env.examplewith dummy values
Memory Leaks
- Event listeners accumulate —
removeListenerwhen done, or useonce - Closures capturing large objects — nullify references when done
- Global caches grow unbounded — use LRU cache with size limit
--max-old-space-sizeto increase heap — but fix leaks first
Streams
- Backpressure:
write()returns false when buffer full — wait fordrainevent .pipe()handles backpressure automatically — prefer over manual read/write- Error handling on all streams —
stream.on('error', handler)or pipeline errors silently pipeline()over.pipe()— handles errors and cleanup properly
Common Mistakes
JSON.parsethrows on invalid JSON — wrap in try/catchrequire()is cached — same object returned on repeated calls- Circular dependencies partially work — but export may be incomplete at require time
asyncfunction always returns Promise — even if you return plain valueBuffer.from(string)encoding matters — default is UTF-8, specify if different