anomaly/variables-module
A Laravel/PHP module for defining and managing reusable variables in your application, providing a lightweight foundation for centralized variable storage, retrieval, and integration with your existing services and views.
Architecture fit. anomaly/variables-module is not a standalone Laravel package — it is a Streams Platform addon from the Anomaly Labs ecosystem (the vendors behind PyroCMS). It is installed as type: stream-addon, discovered through the Streams addon registry, and bootstrapped via VariablesModuleServiceProvider. That means the architecture only "fits" a host application that already runs anomaly/streams-platform (and realistically PyroCMS 3.x). In a vanilla Laravel application the package has no meaningful entry point: its service provider expects the Streams container, addon repository, \Anomaly\Streams\Platform\Addon\Module\Module base class, control panel routes, and Vue-based admin assets. Functionally it provides two primitives — variables (named, typed key/value settings organized into groups, editable through the control panel and exposed to views) and bits (small reusable fragments of editable content) — which in a plain Laravel app are better served by config(), a settings package, or a simple Eloquent model.
Integration feasibility. Low for anything outside the Anomaly ecosystem. Realistically the only viable path is "we are already on PyroCMS/Streams and want the stock variables admin." Integrating into a greenfield Laravel app would require adopting the entire Streams Platform first, which is a platform decision, not a package decision.
Technical risk. High:
addon.php, compiled assets) that is invisible in the composer manifest — a classic hidden dependency for estimation.Key questions.
composer.json constraints — Laravel, PHP, and anomaly/streams-platform versions? Is it installable on our target stack at all?php artisan addon:publish) we must operationalize?Stack fit. Only fits a PyroCMS 3.x / Streams Platform 1.x host. If our application is standard Laravel (Eloquent + Blade/Livewire/Inertia), the correct answer is do not integrate; reimplement the two features natively. The feature set — typed named variables grouped by namespace, plus simple content fragments — is roughly a two-table schema plus a settings UI, i.e., days of work, not weeks.
Migration path. Two options:
addon:install → publish assets → migrate. Accepts the platform lock-in as a deliberate trade-off.variables table (namespace, key, type, value, group) and a bits table (slug, type, content), back them with a cached repository (Cache::rememberForever invalidated on save), expose a small admin CRUD screen, and enforce per-type casting/validation. This preserves the conceptual model and drops the dead dependency.Compatibility. Verify PHP 8.x compatibility (str_contains, typed properties, return types), Laravel version constraints, and whether composer update resolves at all in our lockfile. Expect to pin and possibly patch. Also confirm the front-end asset pipeline (the control panel's Vue bundles) builds under our Node toolchain — often the first thing to break in dormant addons.
Sequencing. (1) Timeboxed spike: attempt install in a throwaway Streams app and confirm it boots and renders. (2) If the host is not Streams, close the spike and schedule the native reimplementation instead. (3) If we proceed, fork to our namespace immediately, pin versions, add CI (install + migrate + smoke test) before writing product code. (4) Only then integrate into the product branch.
Maintenance. Effectively we become the maintainer. With zero dependents and an inactive upstream, there is no one else to absorb Laravel/PHP upgrade work. Budget a standing fork-maintenance line item (dependency bumps, security patches, asset rebuilds) and treat the module as internal code, not a vendor dependency.
Support. None. No maintainer responsiveness, no issue triage, no advisory feed. Incident response is entirely in-house; there is no upstream to escalate to and no known-issue database to search.
Scaling. Reads are the concern: variables are typically resolved during view rendering, so an uncached lookup per render becomes an N-queries-per-request problem at traffic. Mitigate with an application-level cache layer and explicit invalidation on write — do not assume the module does this for you. The tables themselves are tiny, so storage scaling is a non-issue; render-path query volume is the real risk. Content "bits" embedded in pages also complicate CDN/edge caching since edits must purge downstream caches.
Failure modes.
Ramp-up. Non-trivial for anyone who has not worked with Streams: engineers must learn the addon lifecycle, the Module/FieldType abstractions, and the control-panel conventions before they can debug a single variable. Estimate several days of onboarding per engineer, versus hours for the native reimplementation. Given the 0.33 score and zero dependents, the TPM recommendation is to avoid adoption as a dependency and, at most, use the module as a reference design for an in-house variables/bits implementation.
How can I help you explore Laravel packages today?