Lightweight Bun process manager. Use bgrun to start, stop, restart, watch, and monitor background processes — with built-in web dashboard, TOML config, Docker support, and programmatic API.
Resources
11Install
npx skillscat add 7flash/bgrun Install via the SkillsCat registry.
SKILL.md
bgrun — Bun Background Runner
Use bgrun to manage long-running processes. It handles spawning, PID tracking, log capture, port detection, file watching, and provides a web dashboard — all backed by SQLite.
Quick Reference
# Install globally
bun install -g bgrun
# Start a process
bgrun --name my-api --command "bun run server.ts" --directory ~/projects/api
# List all processes
bgrun
# View process details
bgrun my-api
# View logs
bgrun my-api --logs
# Stop / restart / delete
bgrun --stop my-api
bgrun --restart my-api
bgrun --delete my-api
# Launch web dashboard
bgrun --dashboardArchitecture
src/
├── index.ts # CLI entry point — parseArgs + command dispatch
├── api.ts # Public API re-exports (package entry: "bgrun")
├── build.ts # Bun.build script for CLI binary
├── db.ts # SQLite database (sqlite-zod-orm) — schema, queries, mutations
├── types.ts # CommandOptions interface
├── platform.ts # Cross-platform process management (Windows + Unix)
├── utils.ts # Utility functions (parseEnv, runtime calc, tailFile, version)
├── config.ts # TOML/TS config file parser → env vars
├── logger.ts # Boxen-based announce/error display
├── table.ts # Terminal table rendering (hybrid horizontal + vertical tree)
├── server.ts # Dashboard HTTP server (Melina.js)
└── commands/
├── run.ts # Start/restart a process
├── list.ts # List all processes (table or JSON)
├── logs.ts # Show stdout/stderr logs
├── details.ts # Show detailed process info
├── watch.ts # Watch mode — auto-restart on file changes
└── cleanup.ts # Stop, delete, clean, nuke commands
dashboard/
└── app/ # Melina.js file-based routing
├── layout.tsx # Root layout (header, version badge)
├── page.tsx # Server-rendered page shell
├── page.client.tsx # Client interactivity (DOM manipulation, polling)
├── globals.css # Dashboard styles
└── api/ # REST API routes
├── processes/ # GET list, DELETE by name
├── logs/ # GET stdout/stderr by name
├── start/ # POST create process
├── stop/ # POST stop by name
├── restart/ # POST restart by name
└── version/ # GET bgrun version
examples/
├── guard.ts # Single-process guard (auto-restart)
├── guard-all.ts # Multi-process guard (memory limits, restart intervals)
├── bgr-startup.sh # Systemd startup script
├── bgr-startup.service # Systemd service file
├── table.ts # Table rendering demo
├── long-worker.js # Test worker (long-running)
└── test-worker.js # Test worker (short-lived)
tests/
├── bgr.test.ts # Integration tests (process start, config persistence)
└── table.test.ts # Unit tests (column width calculation, rendering)Key Concepts
Database (src/db.ts)
- Uses
sqlite-zod-ormwith a singleprocesstable - Schema fields:
pid,workdir,command,name,env,configPath,stdout_path,stderr_path,timestamp - DB file lives at
~/.bgr/bgr_v2.sqlite(configurable viaDB_NAMEenv) retryDatabaseOperation()handlesSQLITE_BUSYwith exponential backoff
Process Model (src/types.ts + src/db.ts)
CommandOptions— CLI input (name, command, directory, flags)Process— DB record type (inferred from Zod schema +id)
Platform Layer (src/platform.ts)
All process operations are cross-platform (Windows taskkill/wmic/netstat vs Unix kill/ps/ss/lsof):
isProcessRunning(pid)— checks PID or Docker container statusterminateProcess(pid)— kills children first, then parentgetProcessPorts(pid)— OS-level port detection vianetstat/sskillProcessOnPort(port)— force-kill anything on a portfindChildPid(parentPid)— traverse process tree to find leaf PIDgetShellCommand(cmd)— returns["cmd", "/c", cmd]or["sh", "-c", cmd]
Config System (src/config.ts)
TOML/TS config files are flattened to env vars:
{ server: { port: 3000 } } → SERVER_PORT=3000CLI Flow (src/index.ts)
parseArgs()extracts flags and positionals- Internal
--_serveflag → start dashboard HTTP server --dashboard→ spawn the dashboard as a bgrun-managed process- Other flags dispatch to command handlers in
src/commands/ - Default: no args →
showAll(), name only →showDetails(name)
Development Workflow
Build
bun run build # Compiles src/index.ts → dist/index.js (ESM, external packages)Test
bun test # Run all tests
bun test tests/table.test.ts # Run table tests only
bun test tests/bgr.test.ts # Run integration tests (spawns processes)Run locally (dev)
bun run src/index.ts --help # CLI help
bun run src/index.ts --name test --command "bun --version" --directory .
bun run src/index.ts # List processes
bun run src/index.ts --dashboard # Launch dashboardPublish
bun run build
npm publishCommon Tasks
Adding a new CLI flag
- Add the flag to
parseArgs()options insrc/index.ts - Add it to the
showHelp()text - Handle it in the command dispatch section of
run() - If it needs new types, add to
CommandOptionsinsrc/types.ts - Export new functionality from
src/api.tsif it should be public
Adding a new dashboard API endpoint
- Create
dashboard/app/api/<endpoint>/route.ts - Export handler functions:
GET,POST,DELETE, etc. - Import from
../../src/...for database/platform access
Modifying the database schema
- Update the Zod schema in
src/db.ts - The
Processtype is auto-inferred from the schema - Update any insert/query functions that reference changed fields
- Bump the database filename version suffix if migration is needed
Environment Variables
| Variable | Description |
|---|---|
DB_NAME |
Custom database file name (default: bgr) |
BGR_GROUP |
Assign process to a group for --filter |
BUN_PORT |
Explicit dashboard port (no fallback) |
BGR_KEEP_ALIVE |
Set true on a process for guard scripts to monitor |
BGR_MEMORY_LIMIT |
Memory limit for guard scripts (e.g. 500m) |
BGR_RESTART_INTERVAL |
Auto-restart interval in minutes for guard scripts |
Programmatic API
import {
// Types
type Process,
type CommandOptions,
// Database
db, getAllProcesses, getProcess, insertProcess,
removeProcess, removeProcessByName, removeAllProcesses,
retryDatabaseOperation,
// Process operations
isProcessRunning, terminateProcess, readFileTail,
getProcessPorts, findChildPid, findPidByPort,
getShellCommand, killProcessOnPort, waitForPortFree,
ensureDir, getHomeDir, isWindows,
// High-level commands
handleRun,
// Utilities
getVersion, calculateRuntime, parseEnvString, validateDirectory,
} from 'bgrun'Full CLI Reference
| Option | Description |
|---|---|
--name <name> |
Process name (required for start) |
--command <cmd> |
Command to execute (required for start) |
--directory <path> |
Working directory (required for start) |
--config <path> |
Config file (default: .config.toml) |
--force |
Kill existing + clean ports |
--fetch |
Git pull before start |
--watch |
Auto-restart on file changes |
--stdout <path> |
Custom stdout path |
--stderr <path> |
Custom stderr path |
--json |
JSON output for list |
--filter <group> |
Filter by BGR_GROUP |
--logs |
Show logs |
--log-stdout |
Stdout only |
--log-stderr |
Stderr only |
--lines <n> |
Number of log lines |
--stop <name> |
Stop a process |
--restart <name> |
Restart a process |
--delete <name> |
Delete a process |
--clean |
Remove stopped processes |
--nuke |
Delete ALL processes |
--dashboard |
Launch web dashboard |
--port <n> |
Dashboard port (default: 3000) |
--version |
Show version |