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

relife2

v1.0.3

Published

Process manager for Node.js & Bun apps — a predictable PM2 alternative: exactly one locked daemon, no silent self-duplication, Bun as a first-class citizen.

Readme

relife2 — your apps stay up. Period.

The PM2 you wish you had from day one — without the gotchas.

npm version license: MIT node ≥20 bun first-class linux-first

You run 5–10 apps on one VPS. PM2 was great — until pm2 update silently spawned a second daemon, pm2 save was forgotten after a reboot, and bun apps ran as node with extra overhead. relife2 is the fix.


Why teams switch from PM2

| PM2 pain you know | relife2 answer | |---|---| | pm2 update duplicates the God daemon → 2→4→8 daemons, OOM | Exactly one daemon, always. Socket bind + flock. Second daemon can't start. daemon-upgrade is explicit and locked. | | Reboot wipes everything if you forgot pm2 save | Autosave on by default. Every change hits snapshot.json + journal. Reboot → systemd + linger → all apps back. | | interpreter: bun actually runs as node | Bun is first-class. bun <script> directly, auto-detect via bun.lockb/bun.lock, bun --hot in dev. | | Log files grow forever (needs pm2-logrotate) | Built-in rotation: rotate --max-size --retain with gzip, no plugin. | | Unknown config fields silently ignored | Honest errors: warnings for unknown fields, errors for incompatible combos. | | Daemon is heavy (God ~60–90 MB) | Light: ~20–30 MB RSS daemon, no God overhead. |

One command to prove it:
relife2 doctor — checks snapshot, lock, orphans, transport, uptime. PM2 has no equivalent.

Who is it for

  • Solo dev / small team with 5–15 apps on a single Oracle Linux 9 / Debian / Ubuntu VPS (the primary target — developed on Windows, but Linux-first)
  • You use Caddy for TLS/reverse proxy and want real supervision for the upstreams
  • You ship Bun + Node mix (Nuxt, Astro, bots, Java services, Rust binaries)
  • You are tired of babysitting processes

If you run Kubernetes for everything, you don't need this. If you run a VPS and want systemd-grade reliability without writing unit files by hand — you do.


30-second demo

npm i -g relife2            # or: curl single binary → /usr/local/bin/relife2
relife2 start ecosystem.config.cjs
relife2 list
relife2 logs web -f         # follow
relife2 doctor              # 5 checks, exit 1 on error
relife2 startup             # systemd user unit + loginctl enable-linger
# reboot → everything is back. No pm2 save dance.

Migrate from PM2 in one line:

relife2 import-pm2 ~/.pm2/dump.pm2 && relife2 list   # reads PM2 dump, starts via relife2
relife2 from-caddy /etc/caddy/Caddyfile --dry-run    # Caddyfile → relife2.config.cjs

Find forgotten configs (the PM2 paper trail):

relife2 find                       # scans $HOME depth 6
relife2 find --root /opt --depth 8 --json | jq .
relife2 find start                 # starts every stopped config it found

Features that sell themselves

  • Single binary deploy: bun build --compile → relife2-linux-x64 (~40–60 MB). No Node/Bun on the VPS. tar.gz / .rpm / .deb ready.
  • Forgotten-path healing: moved from /home/debian to /opt? Configs with stale cwd/script auto-fix (tries ~/tail, sourceDir, basename search) and logs not found → auto-fixed instead of crash-looping.
  • Caddy-native: from-caddy parses reverse_proxy/php_fastcgi loopback upstreams, generates one app per port with HOST/PORT/SITE_URL, finds entry (Nuxt .output/server/index.mjs etc.), --dry-run plan before writing.
  • Dev that doesn't fight you: relife2 dev ./server.ts --watch ./src --hot → bun --hot for .ts, fs.watch otherwise. q to quit.
  • Upgrade without drama: relife2 daemon-upgrade — save → shutdown old → spawn new → resurrect under lock, protocol version checked. No silent second daemon.
  • Observability out of the box: list / describe / metrics (daemon + per-app RSS) / monit TUI / logs --lines -f.
  • PM2-compatible config surface: ecosystem.config.{js,cjs,mjs,json} + relife2.config.ts, all 8 example/ configs work without edits (golden tests).

Installation

npm (any OS, Node ≥20):

npm i -g relife2
relife2 --version   # relife2 1.0.1 (node)
rl2 --version       # alias

Single binary (VPS — recommended, no runtime on target):

npm run build:single:linux        # → dist/relife2-linux-x64
scp dist/relife2-linux-x64 vps:/usr/local/bin/relife2
ssh vps 'chmod +x /usr/local/bin/relife2 && relife2 --version'
# or from GitHub Releases:
curl -L https://github.com/<org>/relife2/releases/latest/download/relife2-linux-x64 -o /usr/local/bin/relife2
chmod +x /usr/local/bin/relife2

tar.gz / rpm / deb:

npm run dist:tar   # → dist/relife2-1.0.1-linux-x64.tar.gz (binary + README + LICENSE)
npm run dist:rpm   # → dist/relife2-1.0.1-1.x86_64.rpm  (needs fpm)
npm run dist:deb   # → dist/relife2_1.0.1_amd64.deb     (uses dpkg-deb or fpm)
sudo dnf install ./dist/relife2-*.rpm        # Oracle Linux / RHEL / Fedora
sudo apt install ./dist/relife2_*_amd64.deb     # Debian / Ubuntu

All packages install /usr/bin/relife2 + /usr/bin/rl2; autostart is still relife2 startup (user unit) so it respects XDG_RUNTIME_DIR.

Autostart (Linux):

relife2 startup        # writes ~/.config/systemd/user/relife2.service + loginctl enable-linger
systemctl --user daemon-reload && systemctl --user enable --now relife2
systemctl --user status relife2
relife2 doctor

Quick Start

# 1. From a config (PM2-compatible)
relife2 start ecosystem.config.cjs
relife2 list
relife2 logs myapp --lines 100
relife2 doctor

# 2. Single script
relife2 start ./server.js --name myapp -- --port 3000

# 3. Auto-discover relife2.config.* / ecosystem.config.* in cwd
relife2 start

# 4. Zero-downtime reload / scale
relife2 reload myapp
relife2 start --instances max --exec-mode cluster --env production

# 5. Find & rescue forgotten configs
relife2 find --root /opt --depth 8
relife2 find start

# 6. Caddyfile → relife2
relife2 from-caddy /etc/caddy/Caddyfile --dry-run
relife2 from-caddy /etc/caddy/Caddyfile -o relife2.config.cjs && relife2 start relife2.config.cjs

More → docs/CLI.md · docs/CONFIG.md · docs/INSTALL.md


Config at a glance

// ecosystem.config.cjs — same file you use for PM2
module.exports = {
  apps: [{
    name: "web",
    script: "./dist/server/entry.mjs",
    cwd: __dirname,
    interpreter: "bun",          // "bun" | "node" | "none" | "/usr/bin/python"
    args: ["--port", "3000"],    // string or string[]
    instances: "max",            // number | "max" (= cpu count)
    exec_mode: "cluster",
    env: { NODE_ENV: "production", PORT: "3000" },
    env_production: { PORT: "4000" }, // merged with --env production
    env_file: "./.env",          // dotenv, does NOT override real env
    out_file: "./logs/web-out.log",
    error_file: "./logs/web-err.log",
    merge_logs: true,
    time: true,
    log_date_format: "YYYY-MM-DD HH:mm:ss Z",
    autorestart: true,
    max_restarts: 15,
    restart_delay: 3000,
    min_uptime: "10s",
    kill_timeout: 5000,
    max_memory_restart: "512M",
    cron_restart: "0 4 * * *",
    watch: false,                // true | false | ["./src", ".env"]
    watch_delay: 1000,
    wait_ready: false,           // wait for process.send('ready')
  }]
};

Full matrix → docs/CONFIG.md. CLI overrides: relife2 start --env production --instances max.


Bun, Caddy, Linux — first-class

  • Bun: interpreter: "bun" spawns bun directly; auto-detect via bun.lockb/bun.lock or .ts script; relife2 dev ./app.ts uses bun --hot (HMR); bun relife2 ... works (CI matrix node+bun).
  • Caddy: Caddy does TLS/static/proxy, relife2 does supervision. from-caddy + # relife2: dir=… name=… hints.
  • Linux: XDG-first data ($XDG_DATA_HOME/relife2) + runtime ($XDG_RUNTIME_DIR/relife2), RELIFE2_DIR override for tests, /proc RSS, setsid process groups, systemd Restart=always + KillMode=process. SELinux enforcing = experimental (default contexts, no custom policy — author has it disabled).

Development & benchmark

npm install
npm run build        # → dist/cli.js (esbuild, single ESM, shebang)
npm run typecheck && npm run lint && npm test   # 67 tests (m7 integrity inside)
bun dist/cli.js --version
npm run bench        # startup latency + daemon RSS
npm run bench -- --pm2   # compare with PM2 (if installed)

See docs/BENCHMARK.md — numbers are host-dependent, run on your VPS for truth.


License

MIT — see LICENSE. Roadmap → TODO.md, decisions → docs/DECISIONS.md.