@darksol/portguard
v2.0.0
Published
Cross-platform CLI and API to inspect, monitor, and clear localhost port conflicts.
Downloads
33
Maintainers
Readme
Find, inspect, and clear local port conflicts fast — from terminal or code.
What's New in 2.0
Portguard 2.0 adds six major features for full port lifecycle management:
reserve— Hold a port open to prevent conflicts during setuphistory— Track port changes over time with automatic scan loggingconflicts— Detect known service conflicts (26+ built-in port/service mappings)doctor— Health check your port environment (zombies, duplicates, ephemeral range)profile— Save and manage named port configurations for your dev stacksexport— Export port maps as Markdown, CSV, or JSON with host metadata
All features available via CLI and programmatic API. Zero new dependencies.
Why this exists
Port collisions waste dev time: your app won't boot, logs are noisy, and finding the offending process differs by OS. Portguard gives one consistent interface for checking what is listening, killing stale processes, and scripting that flow in CI/dev tooling.
What it does
- Scan active localhost listeners (TCP/UDP) with process metadata
- Check if a specific port is free (
free <port>) - Kill the process bound to a port (
kill <port>) with optional--force - Monitor changes in real time (
watch) - Filter by process name (
find <name>) or range (range <start>-<end>) - Reserve ports to prevent conflicts (
reserve <port>) - Track port history with automatic change detection (
history) - Detect service conflicts against a built-in port database (
conflicts) - Health-check your port environment (
doctor) - Manage named port profiles for dev stacks (
profile) - Export port maps in multiple formats (
export) - Emit machine-readable JSON (
--json) for scripts - Use the same core from a programmatic API
Quickstart
# one-shot
npx @darksol/portguard
# optional global install
npm i -g @darksol/portguard
portguardReal examples
# scan all active listeners
portguard
# free a blocked dev port
portguard kill 3000
# non-interactive kill
portguard kill 3000 --force
# verify database port usage
portguard free 5432
# live monitor
portguard watch
# query by process name
portguard find node
# inspect a bounded range
portguard range 3000-3999
# reserve a port for 60 seconds
portguard reserve 3000 --timeout 60
# show port change history (last 24h)
portguard history
# history for a specific port
portguard history --port 3000 --hours 48
# detect service conflicts
portguard conflicts
# health check
portguard doctor
# save a dev stack profile
portguard profile save my-stack 3000 5432 6379
# check if profile ports are available
portguard profile check my-stack
# free all profile ports
portguard profile free my-stack --force
# export as CSV
portguard export --format csv --out ports.csv
# script-friendly output
portguard scan --jsonProgrammatic usage
import {
scan, isPortFree, killPort, findByName,
reservePort, appendSnapshot, getHistory, diffSnapshots,
detectConflicts, KNOWN_PORTS,
runDoctor,
saveProfile, listProfiles, checkProfile, freeProfile, deleteProfile,
exportPorts,
} from '@darksol/portguard';
// Core
const listeners = await scan();
const free = await isPortFree(3000);
const killed = await killPort(3000);
const nodePorts = await findByName('node');
// Reserve a port for 30 seconds
await reservePort(3000, 30);
// History
appendSnapshot(listeners);
const events = getHistory({ port: 3000, hours: 24 });
// Conflicts
const conflicts = await detectConflicts();
// Doctor
const health = await runDoctor();
// Profiles
await saveProfile('my-stack', [3000, 5432, 6379]);
const profiles = listProfiles();
const status = await checkProfile('my-stack');
// Export
const csv = await exportPorts({ format: 'csv' });
const md = await exportPorts({ format: 'markdown', out: 'ports.md' });Config and options
| Command | Arguments | Flags | Description |
|---|---|---|---|
| scan (default) | none | --json | List active listeners |
| free | <port> | --json | Check if a port is available |
| kill | <port> | --force | Kill process on target port |
| watch | none | --json | Refresh every 2s with change summary |
| find | <name> | --json | Filter listeners by process name |
| range | <start>-<end> | --json | Scan only a numeric port range |
| reserve | <port> | --timeout <sec> | Reserve a port by binding to it |
| history | none | --port, --hours, --json | Show port change history |
| conflicts | none | --json | Detect known service port conflicts |
| doctor | none | --json | Health check for port environment |
| profile | <subcommand> | --json, --force | Manage named port profiles |
| export | none | --format, --out | Export port map |
| help | none | none | Show usage guide with examples |
| (any) | none | --version, -v | Print version number |
Profile subcommands
| Subcommand | Arguments | Description |
|---|---|---|
| save | <name> [ports...] | Save current or specific ports as profile |
| list | none | List all saved profiles |
| show | <name> | Show ports in a profile |
| check | <name> | Check which ports are free/busy |
| free | <name> | Kill processes on profile ports |
| delete | <name> | Remove a saved profile |
Architecture / flow
scannercollects socket/process data per OS:- Windows:
netstat+ PowerShell metadata - Linux:
ss(fallback:netstat) +ps - macOS:
lsof+ps
- Windows:
displayformats table and JSON outputkillerresolves PID and terminates process by portreservebinds a TCP server to hold a porthistorylogs snapshots and diffs consecutive scans for changesconflictscross-references active ports against a known service databasedoctorruns health checks (zombies, duplicates, ephemeral range, etc.)profilemanages named port configurations on diskexportrenders port maps in markdown, CSV, or JSONclihandles argument parsing, command routing, and watch mode
Performance notes
Portguard shells out to native system tools, so speed depends on host load and socket count. Typical local scans complete quickly enough for interactive use; watch mode refreshes every 2 seconds by design.
Limitations + roadmap
Current limitations
- Requires Node.js 18+
- Relies on OS networking tools being available in
PATH watchis a polling loop (2s), not event-stream based
Roadmap
- ~~Add command aliases/help output for discoverability~~ ✅ (v1.0.1)
- ~~Port reservation, history, conflicts, doctor, profiles, export~~ ✅ (v2.0.0)
- Add optional structured error codes for CI pipelines
- Add richer filter options (protocol/state)
Security notes
killterminates local processes; use--forcecarefully- No network calls or telemetry are performed by Portguard
- History and profiles stored locally at
~/.portguard/ - Prefer non-force kill in shared/dev environments to avoid accidental disruption
Development
npm install
npm testLicense + links
MIT © darksol
- Issues: https://github.com/darks0l/portguard/issues
- Repository: https://github.com/darks0l/portguard
- npm: https://www.npmjs.com/package/@darksol/portguard
