Skip to content
Back to skills

Nodejs

ASecurity

Node.js as a scripting, CLI, automation, and file-processing tool across versions 20, 22, 24, and 26: file system operations, child_process/spawn, HTTP fetch with retry/pagination, JSON/CSV/YAML data processing, stream pipelines, argument parsing (parseArgs/commander/yargs), building CLI tools, output formatting (chalk/ora/cli-table3), shell integration (zx/execa), npm/npx workflow, and async concurrency patterns. WHEN: \"Node.js\", \"node\", \"npm\", \"npx\", \"nvm\", \"mjs\", \"cjs\", \"nod...

  • 4 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 24, 2026
toolsrustshellsqlnodenodejsexpresstestinggitapibackend

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 11 files and shows the line behind each finding

Scanned September 24, 2026

npx -y skills add chrishuffman5/domain-expert --skill nodejs --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Nodejs?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Nodejs
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/chrishuffman5-nodejs/badge)](https://www.skillsdirectory.com/skills/chrishuffman5-nodejs)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: nodejs
description: "Node.js as a scripting, CLI, automation, and file-processing tool across versions 20, 22, 24, and 26: file system operations, child_process/spawn, HTTP fetch with retry/pagination, JSON/CSV/YAML data processing, stream pipelines, argument parsing (parseArgs/commander/yargs), building CLI tools, output formatting (chalk/ora/cli-table3), shell integration (zx/execa), npm/npx workflow, and async concurrency patterns. WHEN: \"Node.js\", \"node\", \"npm\", \"npx\", \"nvm\", \"mjs\", \"cjs\", \"node:fs\", \"node:os\", \"child_process\", \"parseArgs\", \"commander\", \"yargs\", \"zx\", \"execa\", \"CLI tool\", \"node script\", \"node automation\", \"node --test\", \"node:sqlite\". Do NOT use for Express/Fastify/NestJS web servers or REST API framework questions — that's the `backend` plugin. This skill covers Node.js as a scripting/CLI/automation tool, not web-service development."
license: MIT
---

# Node.js CLI & Scripting Expert

This skill covers Node.js for scripting, CLI tools, automation, and file processing across all supported LTS and current versions (20, 22, 24, 26). It has deep coverage of:

- File system operations (node:fs/promises, streams, glob, watch)
- Process management (child_process, spawn, exec, fork, signals)
- OS information gathering (node:os, process.env, process.argv)
- HTTP clients (built-in fetch, undici, AbortController, retry/pagination)
- Data formats (JSON, CSV, YAML, streaming JSON)
- Argument parsing (node:util.parseArgs, commander, yargs, meow)
- Async patterns (Promise.all/allSettled/any, concurrency limiting, generators)
- Building CLI tools (bin field, shebang, npm link, interactive prompts)
- Output formatting (chalk/picocolors, ora spinners, cli-table3, boxen)
- Shell integration (zx, execa, shelljs)
- npm/npx workflow (init, install, scripts, workspaces, audit, publish)
- Built-in test runner (node --test) and watch mode (node --watch)

## How to Approach Tasks

1. **Classify** the request type:
   - **File processing** -- Load `references/patterns.md` (file system, streams, data formats)
   - **CLI tool building** -- Load `references/cli-tools.md` (bin field, arg parsing, output, npm)
   - **API/HTTP scripting** -- Load `references/patterns.md` (fetch, retry, pagination)
   - **Shell scripting** -- Load `references/cli-tools.md` (zx, execa, shelljs)
   - **Version features** -- Check the Version-specific guidance table below

2. **Identify version** -- Determine which Node.js version the user targets. If unclear, default to Node 20 (widest LTS compatibility). Version matters for:
   - `Temporal` global date/time API (default-on 26+)
   - `Map`/`WeakMap.getOrInsert()`, `Iterator.concat()` (26+)
   - `node:sqlite` (stable 24+)
   - `require()` ESM (experimental 22, stable 24+)
   - Built-in WebSocket (22+)
   - Built-in glob (22+)
   - Permission model (experimental 20+)

3. **Load context** -- Read the relevant reference file for detailed patterns.

4. **Recommend ESM** -- Default to ESM (`import`/`export`, `.mjs`) for new projects. Note CJS patterns only when targeting legacy codebases.

5. **Prefer built-ins** -- Use `node:fs/promises`, `node:util.parseArgs`, `node:test`, `fetch` before suggesting third-party packages. Note when a built-in requires a minimum version.

6. **Provide runnable examples** -- Include complete, copy-paste-ready code.

## Core Expertise

### File System (node:fs/promises)

```js
import fs from 'node:fs/promises';
import path from 'node:path';

// Read/write files
const text = await fs.readFile('data.txt', 'utf8');
await fs.writeFile('out.json', JSON.stringify(data, null, 2) + '\n');
await fs.appendFile('log.txt', new Date().toISOString() + '\n');

// Directory operations
const entries = await fs.readdir('.', { withFileTypes: true });
const files = entries.filter(d => d.isFile()).map(d => d.name);
await fs.mkdir('nested/dir', { recursive: true });
await fs.rm('old-dir', { recursive: true, force: true });

// Recursive listing
const all = await fs.readdir('/project', { recursive: true });

// File metadata
const stat = await fs.stat('file.txt');
console.log(stat.size, stat.mtime, stat.isDirectory());

// Copy and rename
await fs.copyFile('src.txt', 'dst.txt');
await fs.cp('src-dir', 'dst-dir', { recursive: true });
await fs.rename('old.txt', 'new.txt');
```

### Process and OS

```js
import os from 'node:os';

// System info
os.hostname();           // 'my-host'
os.platform();           // 'linux' | 'darwin' | 'win32'
os.arch();               // 'x64' | 'arm64'
os.cpus().length;        // core count
os.totalmem();           // bytes
os.freemem();            // bytes
os.loadavg();            // [1m, 5m, 15m]

// Process
const args = process.argv.slice(2);
const cwd = process.cwd();
process.env.NODE_ENV ?? '(unset)';
process.exit(1);

// ESM __dirname equivalent
const __dirname = import.meta.dirname; // Node 21.2+

// Signal handling
process.on('SIGINT', () => { cleanup(); process.exit(0); });
process.on('SIGTERM', () => { cleanup(); process.exit(0); });
```

### Child Process

```js
import { exec, execFile, spawn } from 'node:child_process';
import { promisify } from 'node:util';

const execAsync = promisify(exec);
const { stdout } = await execAsync('git log --oneline -5');

// spawn for streaming output
const child = spawn('ls', ['-la']);
child.stdout.pipe(process.stdout);
await new Promise((res, rej) =>
  child.on('close', code => code === 0 ? res() : rej(new Error(`Exit ${code}`)))
);
```

### HTTP (fetch)

```js
// GET with error handling
const res = await fetch('https://api.example.com/users');
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();

// POST with JSON
await fetch('https://api.example.com/items', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ name: 'item' }),
});

// Timeout with AbortController
const ac = new AbortController();
const timer = setTimeout(() => ac.abort(), 5000);
const res2 = await fetch(url, { signal: ac.signal });
clearTimeout(timer);
```

### Argument Parsing (built-in)

```js
import { parseArgs } from 'node:util';

const { values, positionals } = parseArgs({
  args: process.argv.slice(2),
  options: {
    output:  { type: 'string',  short: 'o' },
    verbose: { type: 'boolean', short: 'v', default: false },
    count:   { type: 'string',  short: 'n', default: '10' },
  },
  allowPositionals: true,
});
```

### Async Patterns

```js
// Parallel
const [a, b, c] = await Promise.all([fetchA(), fetchB(), fetchC()]);

// Parallel with error collection
const results = await Promise.allSettled([fetchA(), fetchB()]);

// Concurrency limiting
async function mapConcurrent(items, fn, concurrency = 5) {
  const results = [];
  for (let i = 0; i < items.length; i += concurrency) {
    results.push(...await Promise.all(items.slice(i, i + concurrency).map(fn)));
  }
  return results;
}

// Sleep
import { setTimeout as sleep } from 'node:timers/promises';
await sleep(1000);
```

### Stream Processing

```js
import { createReadStream, createWriteStream } from 'node:fs';
import { pipeline } from 'node:stream/promises';
import { Transform } from 'node:stream';

const upper = new Transform({
  transform(chunk, enc, cb) { cb(null, chunk.toString().toUpperCase()); },
});

await pipeline(createReadStream('in.txt'), upper, createWriteStream('out.txt'));
```

## Common Pitfalls

**1. Using `exec` for untrusted input**
`exec` spawns a shell and is vulnerable to injection. Use `execFile` or `spawn` with argument arrays for user-provided values.

**2. Forgetting `{ recursive: true }` on mkdir**
Without it, creating nested directories throws ENOENT. Always use `{ recursive: true }` unless you intentionally want to fail on missing parents.

**3. Not handling stream errors with pipeline**
Using `.pipe()` does not propagate errors. Always use `pipeline()` from `node:stream/promises` which throws on error and cleans up.

**4. Blocking the event loop with synchronous file I/O**
Use `fs.readFileSync` only at startup for config loading. For everything else, use `node:fs/promises` async methods.

**5. Not setting `"type": "module"` in package.json for ESM**
Without it, `.js` files default to CommonJS. Set `"type": "module"` or use `.mjs` extension.

**6. Ignoring exit codes in CLI tools**
Always call `process.exit(1)` on failure. Scripts used in pipelines or CI depend on non-zero exit codes for error detection.

**7. Hardcoding `__dirname` in ESM**
ESM does not have `__dirname`. Use `import.meta.dirname` (Node 21.2+) or `path.dirname(fileURLToPath(import.meta.url))`.

**8. Not using `--watch` for development**
Node 20+ has built-in `--watch` mode. Use `node --watch script.mjs` instead of installing nodemon.

**9. Using `JSON.parse` without try/catch**
Always wrap in try/catch or use a safe parse helper. Malformed input will throw and crash the process.

**10. Installing packages when built-ins suffice**
Node 20+ has `fetch`, `parseArgs`, `test runner`, `--watch`. Node 22+ has `glob`, `WebSocket`. Node 24+ has `sqlite`. Node 26+ has `Temporal` (replaces date libs like Luxon/Day.js for most needs). Check built-in availability before adding dependencies.

## Version-specific guidance

| Version | Reference | What's version-specific |
|---|---|---|
| 20 LTS | `references/versions/20.md` | Stable test runner, stable fetch, permission model (experimental), SEA, watch mode |
| 22 LTS | `references/versions/22.md` | require() ESM (experimental), built-in WebSocket, built-in glob, snapshot testing |
| 24 LTS | `references/versions/24.md` | node:sqlite stable, require() ESM stable, URLPattern, npm 11 |
| 26 Current | `references/versions/26.md` | Temporal API default-on, V8 14.6 (Map/WeakMap.getOrInsert, Iterator.concat), Undici 8, legacy _stream_*/writeHeader removed |

## Reference Files

Load these when you need deep knowledge for a specific area:

- `references/patterns.md` -- File system operations, process/OS, HTTP fetch with retry/pagination, JSON/CSV/YAML data processing, async patterns, stream processing. Read for scripting and data processing questions.
- `references/cli-tools.md` -- Building CLI tools (bin field, shebang, npm link), argument parsing libraries, output formatting (colors, spinners, tables, progress bars), shell integration (zx, execa, shelljs), npm/npx workflow. Read for CLI tool development questions.

## Scripts

Runnable example scripts demonstrating real-world patterns:

- `scripts/01-system-report.mjs` -- System info report using node:os, node:fs, process
- `scripts/02-api-client.mjs` -- Fetch-based API client with retry, pagination, streaming
- `scripts/03-file-processor.mjs` -- Stream-based CSV-to-JSON file processor with filtering
- `scripts/04-cli-tool.mjs` -- Complete CLI tool with parseArgs, colors, prompts, subcommands

Files in this skill

  • SKILL.md10.6 KB
  • references/cli-tools.md9.7 KB
  • references/patterns.md14 KB
  • references/versions/20.md3.5 KB
  • references/versions/22.md3.7 KB
  • references/versions/24.md5.3 KB
  • references/versions/26.md7.8 KB
  • scripts/01-system-report.mjs3.9 KB
  • scripts/02-api-client.mjs5.4 KB
  • scripts/03-file-processor.mjs5.6 KB
  • scripts/04-cli-tool.mjs7.3 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…