A lightweight systemd compatibility layer for OpenRC-based Linux distributions.
Designed for OpenRC-based distributions such as Artix, Gentoo and Alpine Linux.
Some packages ship .service files and assume systemd. On OpenRC you can either:
- Write init scripts by hand (tedious)
- Convert automatically with compatd
- Run the LD_PRELOAD shim if a binary calls
sd_journal_*/sd_notify
- systemctl-compatible wrapper — preserves muscle memory:
start,stop,enable,disable,status,is-active,is-enabled,daemon-reload,list-units,cat,poweroff,reboot,hibernate - Convert units —
.service→ OpenRC,.timer→ cron,.socket→ s6,.mount→ fstab - LD_PRELOAD shim — minimal implementations of
sd_notify,sd_journal_*,sd_booted,sd_listen_fds,sd_watchdog_enabled,sd_id128_get_machinefor software that calls systemd APIs directly - Socket activation — fd-passing for
-H fd://style services - Cgroup delegation — handles
Delegate=yesvia cgroup v2 - Pacman hook — converts new
.servicefiles automatically after package install - elogind integration — seamless compatibility through
libelogind
# .service → OpenRC
compatd convert service /usr/lib/systemd/system/docker.service > /etc/init.d/docker
chmod +x /etc/init.d/docker
rc-update add docker default
# .timer → cron
compatd convert timer /usr/lib/systemd/system/daily-cleanup.timer >> /var/spool/cron/root
# .socket → s6
compatd convert socket /usr/lib/systemd/system/docker.socket > /etc/s6/docker/run
# .mount → fstab
compatd convert mount /usr/lib/systemd/system/var-data.mount >> /etc/fstabsystemctl start docker
systemctl enable docker
systemctl status docker
systemctl is-active docker
systemctl is-enabled docker
systemctl daemon-reload
systemctl list-units
systemctl cat docker
systemctl poweroff
systemctl reboot
systemctl hibernatecompatd socket-activate --listen-stream /run/docker.sock -- dockerd -H fd://# Build from source (PKGBUILD, Artix/Arch)
git clone https://github.com/DipCrai/compatd
cd compatd && makepkg -si
# Build with Cargo (any distribution)
cargo build --release
# Local install script
./install.sh- Unit parser — custom parser for
.service/.timer/.socket/.mount(no external dependencies) - Unit converter — translates parsed units to OpenRC, cron, s6, fstab
- LD_PRELOAD shim (
libcompatd_preload.so) — provides minimal implementations forsd_notify,sd_journal_*,sd_booted,sd_is_socket,sd_listen_fds,sd_watchdog_enabled,sd_id128_get_machine; journal writes go tosyslog(3), reads return empty - systemctl wrapper — maps 11
systemctlcommands torc-service/rc-update/compatd - Pacman hook — post-transaction script converts newly installed
.servicefiles - elogind — drop-in replacement for
libsystemdwhere applicable
compatd handles the most common unit patterns. Complex features may need manual adjustments:
- Socket activation internals (fd-passing works, but full socket unit lifecycle isn't replicated)
- Transient units (dynamically created by systemd at runtime)
- Advanced cgroup configuration beyond
Delegate=yes - systemd generators and portable services
.path/.slice/.scopeunit types
If you hit something that doesn't convert cleanly, open an issue.