Alex Leko
All content on this blog was fully or partially created using local AI (Apple MLX).

How to Force Your Binary to Stay Alive on macOS

  • macos
  • launchd
  • systemd
  • devops
  • background-services
  • productivity

To move a systemd user service to macOS, configure it as a launchd agent with a Property List (.plist) file.

  1. Create the LaunchAgents directory

Create the directory if it doesn't already exist:

mkdir -p ~/Library/LaunchAgents
  1. Create the service configuration file

Create a file in your editor and give it a reverse-domain name, such as com.yourname.appname.plist:

nano ~/Library/LaunchAgents/com.placeholder.you-app-binary.plist

Paste this template into the file, then replace the placeholder paths and arguments with your own:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.placeholder.you-app-binary</string>
    <key>ProgramArguments</key>
    <array>
        <string>/path/to/your/binary</string>
        <string>extra</string>
        <string>--parmas</string>
        <string>here</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <true/>
    <key>StandardOutPath</key>
    <string>/path/to/your/logs/you-app-binary.out.log</string>
    <key>StandardErrorPath</key>
    <string>/path/to/your/logs/you-app-binary.err.log</string>
</dict>
</plist>

Put the executable and each command-line argument in its own string in the ProgramArguments array.

  1. Set permissions and validate the file

Set the file permissions and check the plist syntax:

chmod 644 ~/Library/LaunchAgents/com.placeholder.you-app-binary.plist
plutil -lint ~/Library/LaunchAgents/com.placeholder.you-app-binary.plist
  1. Enable and start the service

To load and start the service immediately, use the launchctl bootstrap command, the macOS counterpart to systemctl --user enable --now:

launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.placeholder.you-app-binary.plist

Check the service's launchd state with:

launchctl print gui/$(id -u)/com.placeholder.you-app-binary

To stop the service or edit its configuration, unload it first with launchctl bootout gui/$(id -u)/com.placeholder.you-app-binary.