CPU-based process queue daemon that throttles test runners (vitest, jest, playwright) to prevent system overload during development.
- CPU Monitoring: Continuously monitors system CPU usage (overall and system/kernel)
- Daemon Architecture: Background daemon manages queued processes via Unix socket
- Test Runner Interception: Transparently intercepts vitest, jest, and playwright commands
- CLI Management: Full CLI for daemon control, installation, and status monitoring
- Session Metrics: Tracks queue statistics, wait times, and peak usage
- Graceful Fallback: Falls back to direct execution if daemon is unavailable
npm install -g @doryski/node-queue
# or
pnpm add -g @doryski/node-queue# Install shims and PATH configuration
npx node-queue install
# Start the daemon (runs in background)
npx node-queue start
# Or run in foreground for debugging
npx node-queue start -fnpx node-queue statusOnce installed, your test commands (vitest, jest, playwright) will automatically be queued when CPU usage is high.
| Command | Description |
|---|---|
start [-f] |
Start daemon (use -f for foreground) |
stop |
Stop the daemon |
status |
Show daemon status, CPU stats, and queue |
install |
Install PATH modification and build shims |
uninstall |
Remove PATH modification and LaunchAgent |
build |
Build shims only (without PATH installation) |
logs [-f] [-n N] |
Show daemon logs (use -f to follow) |
install-project [-r] |
Patch node_modules/.bin in the current project (auto-run by the pnpm/npm wrappers) |
uninstall-project |
Remove patches from node_modules/.bin |
patch-all --base <dir> |
Recursively patch every project under <dir>. Registers the base for future re-runs |
patch-all |
Re-run patch-all against every previously registered base |
patch-all --forget <dir> |
Remove a base from the registry |
| Variable | Description |
|---|---|
NODE_QUEUE_BYPASS=1 |
Skip queueing, run directly |
NODE_QUEUE_TIMEOUT=N |
Custom timeout in milliseconds (default: 60000) |
NODE_QUEUE_DEBUG=1 |
Enable debug logging in shims |
Default thresholds (in src/config.ts):
maxOverallCpu: 50% - Queue when overall CPU exceeds thismaxSystemCpu: 20% - Queue when system/kernel CPU exceeds this
The library only intercepts commands that go through the shims on your PATH. Locally-resolved binaries (anything in ./node_modules/.bin, which is what pnpm exec vitest, npm test, and editor test runners use) are not intercepted until you patch them with install-project. To avoid running that manually after every pnpm install, node-queue install offers to add pnpm/npm shell wrappers to your shell rc file.
When accepted, the installer appends a guarded block to ~/.zshrc / ~/.bashrc / fish config (wrapped in # node-queue auto-patch wrappers ... # node-queue auto-patch wrappers end markers):
pnpm install|i|add→ runs the realpnpm, then runsnode-queue install-project -p .if./node_modules/.binexistsnpm install|i|add→ same, for npm
Opting out: answer "no" to the prompt during install. Removing later: node-queue uninstall strips the block cleanly.
For one-shot patching of every project under a directory (useful on a fresh machine, or after upgrading node-queue):
# Patch everything under ~/projects and register the base
node-queue patch-all --base ~/projects
# Later, re-run against all registered bases (e.g. after re-installing deps across many repos)
node-queue patch-all
# Stop tracking a base
node-queue patch-all --forget ~/projectsRegistered bases are stored at ~/.node-queue/config.json. The walker skips node_modules (except the top-level .bin it finds), .pnpm, .git, .next, dist, build, and other common build/VCS directories.
- Shim Installation: Creates lightweight shims in
~/.node-queue/bin/for each intercepted binary - PATH Modification: Adds shim directory to the front of PATH
- Interception: When you run
vitest(or other intercepted command), the shim runs instead - Queue Check: Shim connects to daemon, which checks current CPU usage
- Decision: If CPU is low, command runs immediately. If high, it's queued until CPU drops.
vitestjestplaywright
import { createCpuMonitor, createProcessQueue, createMetricsTracker } from '@doryski/node-queue';
// Create a CPU monitor
const monitor = createCpuMonitor(500);
await monitor.start();
// Get current stats
const stats = monitor.getStats();
console.log(`CPU: ${stats.overall}%`);
// Create a queue
const queue = createProcessQueue(100);- macOS: Full support including LaunchAgent for auto-start on login
- Linux: Core daemon and queueing work; no systemd service file included yet (PRs welcome)
- Windows: Not supported — the daemon uses Unix sockets and POSIX signals
Note: The
installcommand's LaunchAgent setup is macOS-only. On Linux, you'll need to manage the daemon process yourself (e.g., via systemd or a process manager).
Releases are driven by a git tag and published automatically by GitHub Actions.
pnpm releaseThe interactive script:
- Verifies the working tree is clean and you're on
main. - Proposes the next patch version (based on the latest
v*tag) — you can override. - Bumps
package.json, commits, tagsvX.Y.Z, and pushes both.
On tag push, .github/workflows/release.yml runs build + lint + tests, verifies package.json matches the tag, then publishes to npm with provenance and creates a GitHub Release with auto-generated notes.
One-time setup: add an NPM_TOKEN repository secret (create an automation token at https://www.npmjs.com/settings/~/tokens, scope Automation or Publish).
MIT