npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

kproc

v2.1.0

Published

Production-grade process and port management utility - Kill processes by PID, port, range, or pattern with verification, retry, and zero dependencies

Downloads

204

Readme

kproc

Production-grade, cross-platform process and port management for Node.js.
Kill processes by PID, port, port range, or pattern with process tree cleanup, retry escalation, and zero dependencies.

npm version License: MIT Node.js Version Zero Dependencies TypeScript Tests


⚡ Highlights

  • 📦 Zero Runtime Dependencies — No bloated node_modules, zero supply chain attack surface.
  • 🚀 Sub-Millisecond Speed — Microsecond process existence checks using native process.kill(pid, 0) syscalls rather than launching slow sub-shells (tasklist / kill -0).
  • 🎯 Exact Port Matching — Eliminates false-positive substring matches on Windows (e.g. port 80 will never mistakenly match 8080 or outbound TCP sockets).
  • 🛡️ Built-in Safety Guards — Protects against accidental suicide of the calling process (process.pid) or critical OS kernel processes (PID 0, 4 on Windows, PID 1 on Unix) unless explicitly overridden.
  • 🌳 Process Tree Termination — Recursively discovers and terminates parent and all child/descendant processes (via taskkill /T on Windows and BFS process tree traversal on Unix).
  • 🔄 Signal Escalation & Verification — Graceful SIGTERM with automatic escalation to SIGKILL if a stubborn process refuses to exit, plus optional cryptographic/kernel death verification.
  • 🐳 Docker & Minimal Linux Ready — Automated fallback chain: lsofssfuser for minimal Alpine/distroless containers.
  • 💎 Modern Dual Package — Full ESM and CommonJS exports with complete TypeScript declaration files (.d.ts / .d.mts).

📊 Feature Comparison

| Feature | kproc | fkill | kill-port | tree-kill | |:---|:---:|:---:|:---:|:---:| | Runtime Dependencies | 0 | 10+ | 1 | 0 | | Kill by Port | ✅ | ✅ | ✅ | ❌ | | Kill by Port Range | ✅ | ❌ | ❌ | ❌ | | Kill by PID | ✅ | ✅ | ❌ | ✅ | | Kill by Name / Regex | ✅ | ✅ | ❌ | ❌ | | Process Tree Cleanup | ✅ | ✅ | ❌ | ✅ | | Host Suicide Safety Guard | ✅ | ❌ | ❌ | ❌ | | Native Microsecond Checks | ✅ | ❌ | ❌ | ❌ | | Retry & Signal Escalation | ✅ | ❌ | ❌ | ❌ | | Zero Substring False-Positives | ✅ | ❌ | ❌ | N/A | | ESM + CJS Dual Export | ✅ | ESM only | CJS only | CJS only |


📦 Installation

# pnpm
pnpm add kproc

# npm
npm install kproc

# yarn
yarn add kproc

# bun
bun add kproc

🚀 Quick Start

1. Free Up a Port (Most Common)

import { killByPort } from 'kproc';

// Terminate whichever process is listening on port 3000
const result = await killByPort(3000, { tree: true, verify: true });

if (result.success) {
    console.log(`Port 3000 freed! (Killed PID: ${result.pid})`);
}

2. Kill by PID with Verification & Tree Cleanup

import { killByPid } from 'kproc';

const result = await killByPid(14820, {
    tree: true,     // Terminate all descendant child processes
    verify: true,   // Confirm kernel has removed process from table
    retries: 3      // Auto-retry up to 3 times on transient failure
});

console.log(result);
// { pid: 14820, success: true, verified: true, signal: 'SIGTERM' }

3. Kill Multiple Ports & Port Ranges

import { killByPorts, killByPortRange } from 'kproc';

// Kill specific development ports in parallel
await killByPorts([3000, 3001, 8080, 8081]);

// Kill an entire range of ports
await killByPortRange(4000, 4010, { tree: true });

4. Kill by Name or Regex

import { killByName } from 'kproc';

// Kill all processes named "chrome"
await killByName('chrome', { tree: true });

// Kill using regular expressions
await killByName('node.*--inspect', {
    useRegex: true,
    tree: true
});

5. Inspect Process & Port Metadata

import { findPidsByPort, getProcessInfo } from 'kproc';

// Discover PIDs bound to port 8080
const [pid] = await findPidsByPort(8080);

if (pid) {
    const info = await getProcessInfo(pid);
    console.log(info);
    // {
    //   pid: 14208,
    //   name: "node.exe",
    //   command: "node server.js",
    //   ports: [8080],
    //   parentPid: 9812,
    //   memoryUsage: "48 MB"
    // }
}

🛡️ Safety Guards

kproc includes production safeguards to prevent accidental self-termination or catastrophic system crashes:

import { killByPid, InvalidInputError } from 'kproc';

try {
    // ❌ By default, kproc blocks attempts to kill the current Node process:
    await killByPid(process.pid);
} catch (error) {
    if (error instanceof InvalidInputError) {
        console.error('Safety guard triggered:', error.message);
        // "Refusing to kill current process (PID: ...). Set allowCurrentProcess: true if this is intentional."
    }
}

// ✅ Explicit opt-in when self-termination is intended:
await killByPid(process.pid, { allowCurrentProcess: true });

Similarly, system-critical PIDs (PID 0 and 4 on Windows, PID 1 on Unix) are protected unless { force: true } is supplied.


📚 API Reference

Process Termination

| Function | Parameters | Return Type | Description | |:---|:---|:---|:---| | killByPort(port, options?) | port: number, options?: KillOptions | Promise<KillResult> | Terminate process listening on given port | | killByPorts(ports, options?) | ports: number[], options?: KillOptions | Promise<KillResult[]> | Terminate processes on multiple ports in parallel | | killByPortRange(start, end, options?) | start: number, end: number, options?: KillOptions | Promise<KillResult[]> | Terminate all processes bound to ports in range | | killByPid(pid, options?) | pid: number, options?: KillOptions | Promise<KillResult> | Terminate process by PID with retry and escalation | | killByPids(pids, options?) | pids: number[], options?: KillOptions | Promise<KillResult[]> | Terminate multiple PIDs in parallel | | killByName(pattern, options?) | pattern: string, options?: FindByNameOptions & KillOptions | Promise<KillResult[]> | Terminate processes matching substring or regex |

Inspection & Lookup

| Function | Parameters | Return Type | Description | |:---|:---|:---|:---| | findPidsByPort(port, options?) | port: number, options?: PortLookupOptions \| number | Promise<number[]> | Get array of PIDs bound to a port | | findPidByPort(port, options?) | port: number, options?: PortLookupOptions \| number | Promise<number> | Get main PID on port (throws ProcessNotFoundError if none) | | findPortsByPid(pid, timeoutMs?) | pid: number, timeoutMs?: number | Promise<number[]> | Reverse lookup: list ports opened by PID | | findPidsByName(pattern, options?) | pattern: string, options?: FindByNameOptions | Promise<number[]> | Find PIDs matching name or regex | | getProcessInfo(pid, timeoutMs?) | pid: number, timeoutMs?: number | Promise<ProcessInfo> | Retrieve process name, command, parent PID, ports, memory | | isProcessAlive(pid) | pid: number | Promise<boolean> | Microsecond check if process exists in OS table |

Options Interfaces

export interface KillOptions {
    /** Signal to send on Unix systems (ignored on Windows). Default: "SIGTERM" */
    signal?: UnixSignal;

    /** Simulate kill without actually terminating the process. Default: false */
    dryRun?: boolean;

    /** Kill process tree (parent and all descendant children). Default: false */
    tree?: boolean;

    /** Maximum time in milliseconds to wait for system operations */
    timeoutMs?: number;

    /** Auto-escalate from SIGTERM to SIGKILL if process won't exit (Unix). Default: false */
    forceAfterTimeout?: boolean;

    /** Delay before escalating to SIGKILL. Default: 3000ms */
    escalationDelayMs?: number;

    /** Verify process is dead after kill attempt. Default: false */
    verify?: boolean;

    /** Retry attempts if kill command fails. Default: 0 */
    retries?: number;

    /** Enable verbose debug logging for this operation. Default: false */
    debug?: boolean;

    /** Safety guard: Allow killing process.pid. Default: false */
    allowCurrentProcess?: boolean;

    /** Force kill, bypassing checks on critical system PIDs (0, 4 on Windows, 1 on Unix). Default: false */
    force?: boolean;
}

⚠️ Error Hierarchy

All custom errors inherit from KProcError, featuring machine-readable code properties and error cause chains:

import {
    KProcError,
    ProcessNotFoundError,     // code: "PROCESS_NOT_FOUND"
    CommandExecutionError,    // code: "COMMAND_EXECUTION_FAILED"
    TimeoutError,             // code: "OPERATION_TIMEOUT"
    InvalidInputError         // code: "INVALID_INPUT"
} from 'kproc';

try {
    await killByPort(3000);
} catch (error) {
    if (error instanceof ProcessNotFoundError) {
        console.log('Port 3000 is already free.');
    } else if (error instanceof KProcError) {
        console.error(`kproc failed [${error.code}]:`, error.message);
    }
}

🐳 Docker & Minimal Linux Environments

In stripped-down Docker images (such as node:alpine or node:slim), the standard lsof tool might not be pre-installed.

kproc automatically handles this:

  1. Attempts lsof -t -i :<port>
  2. Falls back to ss -lntp '( sport = :<port> )'
  3. Falls back to fuser <port>/tcp

If using Alpine Linux and you want maximum speed, you can optionally install lsof:

RUN apk add --no-cache lsof

📄 License

MIT © binh-dev-k2