| name | bgrun |
| description | 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. |
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
bun install -g bgrun
bgrun --name my-api --command "bun run server.ts" --directory ~/projects/api
bgrun
bgrun my-api
bgrun my-api --logs
bgrun --stop my-api
bgrun --restart my-api
bgrun --delete my-api
bgrun --dashboard
Architecture
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-orm with a single process table
- Schema fields:
pid, workdir, command, name, env, configPath, stdout_path, stderr_path, timestamp
- DB file lives at
~/.bgr/bgr_v2.sqlite (configurable via DB_NAME env)
retryDatabaseOperation() handles SQLITE_BUSY with 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 status
terminateProcess(pid) — kills children first, then parent
getProcessPorts(pid) — OS-level port detection via netstat/ss
killProcessOnPort(port) — force-kill anything on a port
findChildPid(parentPid) — traverse process tree to find leaf PID
getShellCommand(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=3000
CLI Flow (src/index.ts)
parseArgs() extracts flags and positionals
- Internal
--_serve flag → 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
Test
bun test
bun test tests/table.test.ts
bun test tests/bgr.test.ts
Run locally (dev)
bun run src/index.ts --help
bun run src/index.ts --name test --command "bun --version" --directory .
bun run src/index.ts
bun run src/index.ts --dashboard
Publish
bun run build
npm publish
Common Tasks
Adding a new CLI flag
- Add the flag to
parseArgs() options in src/index.ts
- Add it to the
showHelp() text
- Handle it in the command dispatch section of
run()
- If it needs new types, add to
CommandOptions in src/types.ts
- Export new functionality from
src/api.ts if 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
Process type 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 {
type Process,
type CommandOptions,
db, getAllProcesses, getProcess, insertProcess,
removeProcess, removeProcessByName, removeAllProcesses,
retryDatabaseOperation,
isProcessRunning, terminateProcess, readFileTail,
getProcessPorts, findChildPid, findPidByPort,
getShellCommand, killProcessOnPort, waitForPortFree,
ensureDir, getHomeDir, isWindows,
handleRun,
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 |