sven/env-providers
Env Providers lets Laravel apps register service providers conditionally by environment, so local, staging, and production-only providers can live outside config/app.php and load automatically based on APP_ENV.
What it is. sven/env-providers is a small Laravel package that lets you declare service providers conditionally, keyed by the application's environment, so that providers like Telescope, Debugbar, Ignition, or IDE Helper only register in local/staging rather than in production. It works by hooking Laravel's provider-registration step during bootstrap and merging an environment-scoped provider list into the standard providers set.
What changed in v4.2.0. Two categories of change, only one of which matters:
@gogl92) and merged by the maintainer. This is the substantive change and it lands directly on the highest-risk surface in the package: Laravel 11 moved the provider manifest from config/app.php to bootstrap/providers.php and reworked the RegisterProviders bootstrapper. A version of this package that claims Laravel 11 support is a materially different dependency than one that predates the shift.shivammathur/setup-php, ramsey/composer-install 2→3). No runtime impact; it's a signal of a maintained pipeline, not a functional change.No deprecations, no documented breaking changes; it's a minor bump. Treat that as a claim to verify rather than a guarantee — the semver-correct widening of a framework constraint can still break consumers if the underlying injection point moved, which is exactly what Laravel 11 did.
Architecture fit. Unchanged and still good. The use case is real but narrow. Laravel's native idiom — if ($this->app->environment('local')) { $this->app->register(DebugbarProvider::class); } in AppServiceProvider::register(), or a PHP-computed providers array — is verbose and scatters environment policy. This package centralizes that policy into one declarative file, which is a readability and auditability win once environments multiply (per-PR previews, multi-region staging, blue/green pairs). It does not introduce new runtime architecture; it constrains when an existing framework concept fires. That is the right shape for a package this size.
Integration feasibility. Improved on the dimension that previously gated adoption. The 2024-10 release predated Laravel 11 and was the most likely reason we'd have been blocked at the next framework upgrade; v4.2.0 closes that gap, and does so before we adopt rather than as a fork we'd have to maintain. Composer-installable, MIT, no native extensions, no external services, surface area small enough to review line-by-line in an afternoon. The remaining feasibility question is narrower and sharper than before: does the Laravel 11 path actually work in our application skeleton — i.e. does it read and merge bootstrap/providers.php, and does it cooperate with artisan optimize's deferred-provider manifest under the new bootstrapper? That needs a boot test per environment, not inference from the changelog.
Technical risk. Revised from the prior assessment:
register() may depend on a binding from an earlier provider, and deferred providers are compiled into a manifest at artisan optimize. Laravel 11 changed how the default manifest is loaded. The fact that support arrived via a community PR means it is likely validated against the contributor's application shape, not ours. Highest-priority verification item.APP_ENV was misconfigured on a new environment — routine with preview/staging clones. Adopt with an explicit fail-closed posture and a CI assertion.Overall. The prior assessment concluded "adopt only if you have three or more environments with materially different provider sets; below that bar, the native conditional wins." That recommendation stands — v4.2.0 does not change the value ceiling, which is still a convenience abstraction over ~10 lines of native code. What it changes is the timing question: v4.2.0 is the first version that is not a near-term upgrade liability, and therefore the first version worth baselining on if the environment count justifies adoption at all. Baseline on v4.2.0, not v4.1.0, and do not adopt v4.1.0 to "upgrade later."
Key questions for the maintainer/team:
bootstrap/providers.php (Laravel 11+) and config/app.php (10 and earlier), or only one path? Which does it merge into on 11?RegisterProviders override vs. listener), or only the version constraint and test matrix? The answer determines our upgrade calculus.RegisterProviders override, or a listener? Overrides of framework internals change our upgrade calculus.config:cache + route:cache + Octane?composer dump-autoload package discovery, or is it an explicit opt-in per provider?APP_ENV is unset or unexpected — does it fall through to the base list?Stack fit. Requires a Laravel application (not Lumen), a modern PHP constraint, and illuminate/support compatibility with our pinned framework version. Application-level package, not a library dependency — it must never leak into a shared internal package, or every consumer inherits the environment policy. Fit is good for a single first-party monolith; poor for anything with a frozen bootstrap (some Octane/Swoole setups with pre-booted containers).
Compatibility. This is now the gate that matters, and v4.2.0 changes its content. Verify against our exact minor, not just the constraint range. Specific gates: bootstrap/providers.php (Laravel 11+) coexistence and merge semantics, deferred-provider manifest generation under artisan optimize on 11, Laravel Octane worker boot (providers resolve once per worker, so environment must be fixed at boot — compatible, but rules out per-request environment switching), and PHP version. Confirm whether the package ships its own service provider that must be listed, and where — that answer differs between 10 and 11. If we run a mixed fleet, test both skeletons; do not extrapolate from one.
Migration path.
->register( inside providers, if (app()->environment(...)) guards, bootstrap/providers.php contents, and every package in dont-discover. Produce the target environment × provider matrix as a reviewable artifact before touching code.^4.2.0 exactly, add its provider list alongside existing registrations, and assert via a boot test that the resolved provider set is byte-identical to today's, in every environment. No behavior change in this step. This is where the Laravel 11 support claim gets proven or fails.APP_ENV=production and asserts debug providers are absent. This is the test that protects against the fail-open risk, and it should exist even if we later drop the package.Sequencing. Ship in local and testing first, where a misregistration is invisible; promote to staging; production last, and only after the fail-closed behavior is proven and the post-artisan optimize boot test is green. Keep the change reversible as a single revert commit, and do not bundle it with a framework upgrade — if we are also moving to Laravel 11, land that first, on native conditionals, and add this package afterward against a known-good baseline. Adopting a package and a framework major in the same change makes the inevitable boot failure ambiguous.
Maintenance. Low ongoing effort, but the ownership burden is real and unchanged in kind: we inherit upgrade-testing responsibility for every Laravel major. Budget a recurring line item — "re-verify env-provider bootstrap on framework upgrade" — in the upgrade runbook, with a specific sub-step for the bootstrap/providers.php path now that 11 is in scope. The vendor signal is better than at the prior review (active dependency maintenance, external PR reviewed and merged), so the probability of needing a fork is lower; the cost if needed is unchanged, and given the small footprint a fork remains a realistic, pre-approved fallback rather than a crisis.
Support. No vendor, no SLA, no commercial backing. Internal ownership must be explicit — a named team, an ADR recording why this abstraction exists and what may vary by environment, and a note in onboarding docs. The failure mode to guard against is silent abandonment: the package keeps working, then blocks a framework upgrade at an inconvenient moment. v4.2.0 is evidence that risk is currently being managed, not eliminated — one responsive maintainer is still one person. Mitigate by pinning exactly and keeping the abstraction boundary thin enough to inline in a day.
Scaling. Negligible runtime cost — an array merge at boot, zero per-request overhead. No meaningful effect on request throughput, queue throughput, or memory. The scaling concern is organizational: as environments proliferate, the environment × provider matrix grows combinatorially and becomes its own drift source. Cap it — three environment tiers, not twelve bespoke ones.
Failure modes.
| Failure | Impact | Detection | Mitigation |
|---|---|---|---|
APP_ENV misconfigured on new environment |
Debug/profiling providers register in prod — information disclosure | Config audit; boot test | Fail-closed default; CI assertion per environment |
Laravel 11 providers.php merge regression |
Providers silently missing or duplicated at boot | Boot test on 11 skeleton | Prove parity in the shadow step before cutover; block on it |
| Config cache baked with wrong env list | Stale provider set after deploy | Deploy smoke test | config:clear in deploy; test post-optimize |
| Provider ordering regression | Missing binding, opaque container error at boot | Boot test in CI | Assert resolved provider order, not just presence |
| Deferred-provider manifest mismatch | Provider silently never boots | Feature-level integration test | Run artisan optimize in CI, not just locally |
| Package abandonment | Blocked framework upgrade | Quarterly dependency review | Pin exact version; fork pre-approved |
| Octane/env coupling | Wrong providers in long-lived workers | Octane-specific boot test | Fix env at boot; never switch at runtime |
| Bundling this with a framework major | Ambiguous boot failure, slow rollback | Change review | Land framework upgrade first, separately |
Ramp-up. Trivial for the individual engineer — the mental model is "providers with an environment guard," learnable in under an hour. The real ramp-up cost is the policy decision, not the tool: someone must own the answer to "what may vary by environment," and that answer needs to be written down before the file exists or the list becomes an unreviewed dumping ground. Estimate one engineer-day for inventory and ADR, plus half a day of CI/test work — and one additional focused half-day to verify the Laravel 11 path specifically, which is the only genuinely new work v4.2.0 imposes. Treat the ADR as the deliverable that outlives the package.
How can I help you explore Laravel packages today?