Alternatives and tradeoffs

Copy Markdown View Source

Forcola is not the only way to run external processes from the BEAM. The table below reflects each option's published source and tracker as of mid-2026; rows marked "tested" were verified empirically on macOS with Elixir 1.20 / OTP 29.

OptionArchitectureBEAM-death cleanupGrandchild killInstall footprintMaintenance (mid-2026)
System.cmd / Port / :os.cmdBEAM portNone; no signal on port close (tested)NoNoneOTP/Elixir stdlib
erlexecOne C++ port program for all commandsYes, incl. kill -9: SIGTERM then SIGKILL in 6 sOpt-in ({group, GID} + kill_group)C++ toolchain + rebar3 at dep compile, source-only packageActive (2.3.4, June 2026)
MuonTrapC wrapper per commandYes, incl. kill -9 (tested)Linux cgroups: full tree; macOS: direct child only (tested)C compiler (elixir_make)Active (1.8.0 May 2026, 2.0 rc June 2026)
Porcelain + goonGo middleman, manual downloadCloses child stdin and waits; never killsNogoon fetched by hand; last goon release 2014Unmaintained (last release 2016, last commit 2020)
RamboRust shim per callSIGKILLs direct child on stdin EOFNoBundled x86-64 binaries only; broken out of the box on Apple Silicon (tested)Dormant (last release March 2021)
exileNIF IO + spawner that execs into the commandNormal exits yes; kill -9 of BEAM orphans the child (tested)NoC compiler (elixir_make)Maintained, single author (0.14.0, Feb 2026)
forcolaRust shim per commandstdin EOF kills the process group, covers kill -9; death confirmed before EXITYes (setsid + kill(-pgid), TERM then KILL)None on 5 precompiled targets; cargo elsewhereNew (v0.1.0)

erlexec

The most capable and most mature option: a single C++ port program with pty support, user switching, and opt-in process-group kill, actively maintained since 2003. Its costs are a C++ toolchain at dependency compile time and a larger API surface. forcola now supports a pty in Forcola.Duplex (pty: true), so a pty alone is no longer a reason to reach for erlexec; forcola's pty is Duplex-only and does no RFC 4254 option negotiation. forcola also does a basic run-as-user drop now (#31): :user/:group options do a straight setgroups/setgid/setuid from a privileged shim. erlexec goes further, with a sudo/SUID helper for privilege escalation and Linux capability management; forcola does neither. Choose erlexec when you need those.

MuonTrap

Solves the same core problem as forcola with a per-command C wrapper, and on Linux adds cgroup containment that kills entire process trees, including deliberate daemonizers. Without cgroups it kills the direct child only, so grandchildren escape; forcola's group kill covers ordinary grandchildren everywhere but cannot contain a deliberate daemonizer on macOS either. On Nerves or embedded Linux, MuonTrap is the native choice.

exile

Takes a different shape: NIF-based demand-driven IO with real backpressure, ideal when a slow consumer must stream huge output without buffering. The tradeoff is cleanup: with no middleman process, a kill -9 of the BEAM orphans the child (in testing on macOS, exile's child survived where forcola's and MuonTrap's shims cleaned up). Forcola tracks a backpressure streaming mode in #32.

Porcelain and Rambo

Both are effectively frozen. Porcelain has had no release since 2016 and its goon driver's last release is from 2014; the released goon never kills the child, it only closes stdin and waits. Rambo is a one-shot Rust shim design but has had no release since March 2021, ships x86-64-only binaries, and in testing on an Apple Silicon Mac it failed out of the box. Rambo proved a Rust shim works in a hex package; its binary distribution is the cautionary tale forcola's release workflow is designed around.

Choosing something else

  • You need privilege escalation via a sudo/SUID helper, or Linux capability management: erlexec. forcola does a basic uid/gid drop with :user/:group (#31): a straight setgroups/setgid/setuid from a privileged shim, not sudo/SUID or capabilities.
  • You need Linux cgroup containment of daemonizers today: MuonTrap (or systemd-run). forcola tracks an optional cgroup layer in #15.
  • You need backpressure-first streaming and accept the kill -9 orphan risk: exile. forcola tracks a backpressure mode in #32.
  • You need Windows: Rambo's bundled binary or plain System.cmd. forcola tracks Windows support in #34.
  • You cannot ship native binaries at all: System.cmd/ports, with the orphan-on-death leak documented and accepted.
  • forcola is new (v0.1.0). If that is a blocker, erlexec and MuonTrap are the mature, actively maintained alternatives that cover the closest ground.