Comparison¶
So you’re shopping for a “service object” style gem — nice. This page is a cheat sheet: what CMDx packs in one box versus a few popular friends, without the marketing fluff.
The short story¶
CMDx tries to be the toolkit you reach for when you want one place for logging, telemetry, typed inputs, middleware, retries, and workflow-y execution — while keeping the runtime dependency list boring (mostly stdlib). Other gems are awesome too; they just optimize for different slices of that pie.
Feature matrix (at a glance)¶
✅ = “ships with this idea.” ❌ = “not really a first-class thing here.”
Use the table to answer: “Do I care about this capability out of the box?”
| Feature | CMDx | Actor | Interactor | ActiveInteraction | LightService |
|---|---|---|---|---|---|
| Stdlib-only runtime deps | ✅ | ❌ | ✅ | ❌ | ❌ |
| Typed inputs | ✅ | ✅ | ❌ | ✅ | ❌ |
| Type coercion | ✅ | ❌ | ❌ | ✅ | ❌ |
| Input validation | ✅ | ✅ | ❌ | ✅ | ❌ |
| Built-in logging | ✅ | ❌ | ❌ | ❌ | ✅ |
| Telemetry hooks | ✅ | ❌ | ❌ | ❌ | ❌ |
| Middleware system | ✅ | ❌ | ❌ | ❌ | ✅ |
| Workflow execution | ✅ | ✅ | ✅ | ✅ | ✅ |
| Fault tolerance | ✅ | ❌ | ❌ | ❌ | ❌ |
| Lifecycle callbacks | ✅ | ✅ | ✅ | ✅ | ✅ |
What you get “for free” with CMDx¶
-
Observability — Structured logs and telemetry hooks are part of the design, not something you bolt on later after the third outage.
-
Timing on every run — Each
Resultknows how long the task took (duration, in ms). The:task_executedtelemetry event carries that too, so wiring metrics is usually a small subscriber — not a science project. -
Inputs that behave — Built-in coercers (think “string → integer”, dates, arrays, …) and validators (presence, length, format, …). Both are extensible if you outgrow the defaults.
-
Middleware — Wrap the whole lifecycle (auth, caching, extra logging) without cramming everything into
work. -
Retries and faults — Say
retry_onwith jitter when the network wobbles; usesuccess!/skip!/fail!/throw!for clear outcomes instead of scattering magic return values. -
Parallel workflows (when you need them) — Workflow groups can run work in parallel using registered executors (
:threads,:fibers, or your own) and merge context with registered mergers (:last_write_wins,:deep_merge,:no_merge, or custom). Details: Workflows - Parallel Groups. -
Telemetry you can actually subscribe to — Events like
:task_started,:task_deprecated,:task_retried,:task_rolled_back,:task_executedonly fire if someone is listening — no subscriber, no overhead. -
No framework lock-in — Rails, Hanami, Sinatra, or plain Ruby are all fine. Runtime deps stay small (
bigdecimal,logger); you don’t need ActiveSupport just to exist.
If a row in the table made you go “wait, I need that,” follow the link to the gem that fits — and if several rows are ✅ for CMDx for your app, you might enjoy staying in one ecosystem.