stateforge/scenario-core
A Laravel/PHP package offering core building blocks for scenario-driven features. It provides lightweight primitives and abstractions for defining, organizing, and running scenarios, helping keep application logic clean and reusable across projects.
scenario-core is an abstraction layer for defining and executing scenarios (conditions → transitions → actions) rather than a finished product feature. That makes it a candidate to replace a bespoke internal state-machine/rule-engine effort, or to serve as the skeleton we build on. The decision is less "adopt this library" and more "adopt this vocabulary and core loop, then own the domain layer."if statements in controllers/jobs, or as declarative scenario definitions in one place? This package points at the latter, which is a precondition for ever exposing those flows to ops/config rather than shipping code.Consider it when most of the following hold:
Look elsewhere when any of these are true:
Illuminate\Pipeline will be cheaper to read and cheaper to hand over.Recommended posture if we proceed: timeboxed spike (1–2 weeks), wrapped behind our own ScenarioRunner interface, with an explicit exit plan to Symfony Workflow or an in-house implementation. Success criteria up front: does it remove duplicated conditional logic in ≥2 real flows, and can a mid-level engineer change a flow without reading the package source?
For executives — one paragraph. We have repeated conditional-logic problems (onboarding gates, approval chains, eligibility rules) that we currently rebuild per feature. A small, permissively licensed PHP package, stateforge/scenario-core, gives us a standard way to express those flows and a single place to change and explain them. The financial exposure is near zero — BSD-3 license, no paid tier, no data leaving our systems — and the real cost is a short engineering spike. The real risk is maturity: it has two GitHub stars and no downstream users, so we would own it, not depend on it. Recommendation: fund a two-week spike behind our own interface, measure whether it removes duplicated logic in two live flows, and keep a documented fallback. Treat this as a cheap experiment in shared platform thinking, not a vendor commitment.
For engineering. We'd consume the core as an internal library, pin the version, vendor it if we need to patch, and never call it directly from controllers — everything goes through our own thin interface so the implementation is replaceable. We write the tests and the docs. If the spike doesn't pay for itself in two flows, we delete it and keep the vocabulary.
How can I help you explore Laravel packages today?