unitup v0.1.5
⚡ Zero-Daemon · Linux systemd · macOS launchd · Windows Services

Cross-Platform Service Management,Simplified for Any App.

unitup is a zero-dependency CLI & library to run Node.js, Python, Ruby, PHP, Bun, Deno, Go, Elixir, Shell scripts, and compiled native executables as native background services across Linux (systemd), macOS (launchd), and Windows (Windows Services).

Quick Start bash
npm install -g unitup

# Install & start service natively on Linux, macOS, or Windows
unitup install server.js --name api --start
unitup status api
unitup logs api --follow

# Preview generated native service configuration without installing
unitup install server.js --name api --dry-run

Core Promises

⚡ No Resident Daemon

Exits immediately after configuring services. No resident unitup master process continuously eating CPU or RAM.

🖥️ Cross-Platform

First-class adapters for Linux (systemd), macOS (launchd), and Windows (SCM).

🌐 Multi-Runtime

Out-of-the-box support for Node.js, Python, Ruby, PHP, Bun, Deno, Go, Elixir, Shell, and native binaries.

🔍 Dry-Run Mode

Use --dry-run to inspect exact generated unit files or XML plists before installing.

📦 Zero Dependencies

Built strictly with Node.js standard libraries. Zero heavy third-party npm dependencies or native bindings.

🔄 100% Backward Compatible

Full support for existing Linux systemd workflows, timers, and legacy metadata without breaking changes.

Platform Support Matrix

Unitup provides unified command syntax while leveraging the native service architecture on each operating system:

Feature Linux (systemd) macOS (launchd) Windows (Windows Services)
Install / Uninstall systemd user/system unit launchd agent/daemon .plist Windows Service (sc.exe)
Start / Stop / Restart systemctl launchctl kickstart / kill sc.exe start / stop
Auto-Start on Boot systemctl enable RunAtLoad: true Automatic Service Startup
Environment Variables Environment= EnvironmentVariables plist dict Process Environment Forwarding
Logs journalctl File-based streaming (~/.config/unitup/logs/) File-based streaming (~/.config/unitup/logs/)
Crash Recovery Restart=on-failure KeepAlive plist dictionary Host supervisor auto-restart & uptime reset
User Services ~/.config/systemd/user/ ~/Library/LaunchAgents/ Supported
System Services /etc/systemd/system/ (--system) /Library/LaunchDaemons/ (--system) Native Windows Service
Dry-Run Inspection --dry-run (systemd unit) --dry-run (plist XML) --dry-run (service JSON)

unitup vs PM2

unitup is not a PM2 replacement or an independent process manager. While PM2 runs its own master daemon, unitup is strictly a thin, transparent CLI layer on top of native OS service managers.

Feature unitup PM2
Background Process (Daemon) No resident daemon. OS directly supervises processes. Runs a persistent process-management daemon.
System Integration Native OS service managers (systemd, launchd, Windows Services). Custom process monitoring via PM2's internal daemon.
Multi-Runtime Support Node, Python, Ruby, PHP, Bun, Deno, Go, Elixir, Shell, Native Binaries. Node.js-focused process manager with support for running other commands.
Privileges Required Does not require elevated permissions for user services. Boot integration commonly requires running PM2 startup with elevated privileges.
Dependencies 0 Runtime Dependencies (Node.js standard modules only). Dozens of 3rd party npm packages.
Log Management Native journald (Linux) / Cross-platform streaming tail files. Manages .pm2/logs files (requires pm2-logrotate plugin).

Core Architecture

Unitup generates native service definitions directly from a canonical command + args model:

Linux (systemd unit)

[Unit]
Description=unitup service: worker
After=network.target

[Service]
Type=simple
WorkingDirectory=/home/user/apps
ExecStart=/usr/bin/python3 /home/user/apps/worker.py
Restart=on-failure
RestartSec=3
Environment=APP_ENV="production"

[Install]
WantedBy=default.target

macOS (launchd plist)

<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>dev.unitup.worker</string>
  <key>ProgramArguments</key>
  <array>
    <string>/usr/bin/python3</string>
    <string>/home/user/apps/worker.py</string>
  </array>
  <key>WorkingDirectory</key>
  <string>/home/user/apps</string>
  <key>RunAtLoad</key>
  <true/>
  <key>KeepAlive</key>
  <dict>
    <key>SuccessfulExit</key><false/>
    <key>Crashed</key><true/>
  </dict>
</dict>
</plist>

Supported Runtimes & Auto-Detection

Runtime Extension / Auto-Detection Command Executed
Node.js .js, .mjs, .cjs or shebang #!/usr/bin/env node node <script>
Python .py or shebang #!/usr/bin/env python3 python3 <script>
Ruby .rb or shebang #!/usr/bin/env ruby ruby <script>
PHP .php or shebang #!/usr/bin/env php php <script> (Supports -S 0.0.0.0:8080)
Bun Explicit --runtime bun or shebang #!/usr/bin/env bun bun <script>
Deno Explicit --runtime deno or shebang #!/usr/bin/env deno deno run <script>
Go .go or shebang #!/usr/bin/env go go run <script>
Elixir .ex, .exs or shebang #!/usr/bin/env elixir elixir <script>
Shell .sh or shebang #!/bin/bash / #!/bin/sh bash <script>
Native Executable Explicit --runtime native Direct binary execution (./server)

CLI Reference

unitup doctor

Runs cross-platform diagnostics (Platform, Service manager, Node.js path, data directory, permissions, lingering, and detected runtimes).

unitup doctor

unitup install / add <script|exec> [options]

Generates and installs a new native background service.

# Flags:
# --name         Service name (default: script basename)
# --runtime      Specify runtime (node, python, ruby, php, bun, deno, shell, go, elixir, native)
# --command      Explicit binary executable (bypasses auto-detection)
# --env KEY=val        Set environment variable
# --env-file     Load environment file
# --dry-run            Preview generated service file without installing
# --system             Install as system-wide service (LaunchDaemons / root systemd)
# --start              Enable and start service immediately
# --force, -f          Force overwrite of currently running service

unitup install server.js --name api --start
unitup install worker.py --name worker --group backend --env APP_ENV=production --start
unitup install server.js --dry-run

unitup list / unitup ls

Lists all managed services in a clean aligned table.

unitup list --group backend

unitup inspect <name>

Displays full service configuration overview without revealing secrets or environment variables.

unitup inspect api

unitup start / stop / restart <name|@group>

Controls service state individually or in batch using @group syntax.

unitup start api
unitup restart @backend
unitup stop api

unitup enable / disable <name>

Enables or disables service startup on boot.

unitup enable api
unitup disable api

unitup status / logs <name>

Inspects process status with live metrics or streams service logs with advanced filtering.

unitup status api --verbose
unitup logs api --follow
unitup logs api --lines 50 --grep "ERROR"

unitup uninstall / remove <name|@group> [--force]

Stops, disables, and deletes a service or group. Active running services require --force / -f to prevent accidental deletion.

unitup uninstall api
unitup uninstall @backend --force

Systemd Timer Schedules (Linux)

unitup supports native systemd timer scheduling on Linux without running continuous worker processes or cron daemons.

Schedule Commands

# Create interval schedule (--every 30m)
unitup schedule cleanup.js --every 30m --persistent --start

# Create calendar schedule (--calendar daily with random delay jitter)
unitup schedule backup.py --calendar daily --random-delay 10m --persistent --start

# List all schedule timers
unitup schedules   # or unitup timers

# Detailed schedule status
unitup schedule-status cleanup

Programmatic API

unitup exports full ESM and CommonJS interfaces with complete TypeScript declarations (index.d.ts).

Cross-Platform Service Manager

import {
  ServiceManager,
  getAdapter,
  getPlatformCapabilities,
  createService,
  getServiceStatus,
  listServices
} from "unitup";

// High-level service manager (auto-resolves current OS adapter)
const manager = new ServiceManager();

// Install and start service
await manager.install({
  name: "api",
  script: "./server.js",
  env: { NODE_ENV: "production" }
}, { start: true });

// Check status
const status = await manager.status("api");
console.log(`State: ${status.state}, PID: ${status.pid}, Platform: ${status.platform}`);

// Inspect capabilities
const caps = getPlatformCapabilities();
console.log(`Service Manager: ${caps.serviceManager}`);