Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Env Diff Laravel Package

romanzipp/laravel-env-diff

A Laravel package for comparing .env files side by side, highlighting missing, extra, and mismatched keys so you can spot configuration drift between environments before it causes deployment surprises.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. romanzipp/laravel-env-diff remains a leaf-node developer tool: a service provider, one artisan command, no domain code, no runtime surface. 2.0.0 does add a config file (config/env-diff.php), which is a small but real expansion of the package's footprint — it is no longer purely "command in, command out," it now owns a publishable config artifact with a schema that has already changed once (see below). Fit is still low-risk by construction (require-dev, removable), but the package now has a configuration contract our repo would inherit and must keep in sync.

Integration feasibility. Mechanically still simple, but no longer "no config publishing." 2.0.0 introduces a config file with files, path, and show_values, and renames the command to env:diff. Integration therefore includes a vendor:publish step and a committed config, plus updated runbook references. Composer auto-discovery still applies. The friction is unchanged in kind — version constraints — and now slightly higher in effort because of the new config surface.

Technical risk.

  • Staleness / platform ceiling (high, unchanged). 2.0.0 targets Laravel 7 and PHP 7.4 — it moves the ceiling forward one Laravel major and adds 7.4, but does not reach Laravel 9/10/11 or PHP 8.1+. For a modern codebase this is a hard resolution failure, not a warning. --ignore-platform-reqs remains unacceptable in a governed repo.
  • Adoption signal (high, unchanged). Still a single maintainer with negligible stars/dependents and no visible CI matrix. 2.0.0 is a maintenance release, not evidence of a sustainable project.
  • Secrets exposure (downgraded from medium–high to low–medium). 2.0.0 directly addresses the previous open question: 'show_values' => false is the default, with values behind an explicit --values flag / config toggle. Key-only output is now the out-of-the-box behavior. Residual risk is operational, not design: someone enables --values in a CI job whose logs are externally published.
  • Parsing correctness (medium, unchanged). Dotenv edge cases — quoted values, multi-line values, # comments, escaped $, ${FOO} interpolation, duplicate keys — remain unvalidated. No sign of a fixture-based test suite over these cases.
  • Abandonment (high, unchanged). Still no security response path. A 3.x that supports PHP 8 might land; nothing in 2.0.0 commits to it.
  • New: default path of app_path() (medium). Defaulting env-file resolution to app_path() rather than base_path() is surprising. If the config is published and path is left at default, the command can read the wrong directory, compare two empty/absent files, and report a clean diff — a fail-open in a correctness gate. This is a concrete false-negative path introduced by 2.0.0.

Key questions.

  1. Does the command mask values? Answered by 2.0.0: yes, show_values => false by default, --values opt-in. Confirm the flag cannot be triggered by a stray env var in CI.
  2. Does 2.0.0's composer.json resolve on our target Laravel/PHP matrix? Given the stated Laravel 7 / PHP 7.4 ceiling, assume no until proven.
  3. Does it exit non-zero on drift, so it can gate CI? Still unanswered across both majors.
  4. Does it distinguish "missing from .env" from "extra in .env" from value drift, or only diff key sets? With files now an array, what is the semantics for three or more files — pairwise, or first-vs-rest?
  5. With default path => app_path(), what does the command do when a configured file is absent — error, or silent empty comparison? Fail-open must be ruled out.
  6. Is the parsing layer separable, or welded to the command? This determines fork cost.
  7. Does the 2.0.0 config schema look stable enough to own a committed copy of, given it already broke additional_files → files?

Integration Approach

Stack fit. Unchanged: require-dev only, developer workstation and CI. No production image. The value proposition is still the "env key added to code, forgotten in .env.example" defect class, and 2.0.0 makes that slightly more credible by defaulting to masked output and by letting you list both files explicitly rather than only "additional" ones.

Migration path. Two paths, and the recommendation is unchanged — reimplement — but 2.0.0 shifts the argument's basis.

  • Adopt/fork: 2.0.0 fixes the masking concern, which was the strongest technical objection. But the platform ceiling (Laravel 7 / PHP 7.4) is now the blocker, and forking means owning a config schema that has already churned once, plus a hand-rolled dotenv parser across the edge cases above. Widening constraints to Laravel 10/11 + PHP 8.2 is a non-trivial port, not a constraint bump.
  • Reimplement: still roughly one day. Use vlucas/phpdotenv's existing parser (already a transitive Laravel dependency, no new vendor), read the pair of files into arrays, array_diff_key both directions, two-column table, explicit non-zero exit on drift and on unreadable/unparseable input, opt-in --values behind the same masking posture the package now has. Zero external dependency, correct base_path() resolution, test coverage we control.

The reimplementation case is now marginally weaker on feature parity (we'd rebuild --values, path, multi-file config) and still stronger on total cost of ownership, because the one differentiator the package had — sane masked defaults — is a 20-line decision in our own code.

Compatibility. Blocking, and unchanged in substance. Verify explicitly on the target matrix before any commitment; treat Laravel 7 / PHP 7.4 as the stated support envelope, not a floor to negotiate. No --ignore-platform-reqs in a shared codebase.

Sequencing.

  1. Spike (0.5 day): scratch branch on the target matrix; attempt install; if it resolves, publish config, set path explicitly to base_path(), run against a deliberately awkward .env pair (quoted values, comments, interpolations, a missing key in each direction, a value-only drift) and record masking, exit codes, and behavior when a configured file is absent.
  2. Decision gate: if it fails resolution on our matrix — the expected outcome — go straight to reimplementation. Do not fork by default. Also gate on fail-open behavior for missing files and on exit-code semantics.
  3. Build (1 day): first-party env:diff-equivalent command plus fixture tests over the edge cases; masked by default with an explicit --values opt-in matching the package's posture.
  4. CI wiring (0.5 day): non-blocking PR job for two weeks, watch false-positive rate against intentionally local-only keys, then promote to blocking. Never enable --values in a job with externally published logs.
  5. Documentation: onboarding runbook, contributing guide, and the policy statement that .env.example is the canonical key list.

Operational Impact

Maintenance. Unchanged and decisive: upstream is effectively unmaintained and now sits a platform generation behind. Any Laravel or PHP upgrade converts the dependency into our maintenance. The 2.0.0 config schema is a second artifact we would inherit and must migrate on the next breaking release, if one comes. The reimplementation remains the lower-maintenance option.

Support. No upstream support channel, no release cadence, no security advisory process. 2.0.0 arrived five years after 1.0 with no commitment to a 3.x; it improves the tool but does not improve the support posture. Any bug is ours immediately.

Scaling. Negligible, as before. O(number of keys), sub-second, developer-local or per-CI-job. The only scaling dimension is organizational: adopting the tool spreads the drift-detection convention across repos and should be paired with the documented canonical-key-list policy.

Failure modes.

  • Fail-open on wrong path default — the concrete new risk in 2.0.0: path => app_path() can point at a directory with no env files, yielding an empty comparison and a green build. Mitigate by pinning path to base_path() at integration time and by requiring a non-zero exit when a configured file is absent.
  • Fail-open on parse error — unreadable or unparseable input must exit non-zero, never be treated as empty.
  • Secret leakage via --values — masking is now correct by default, so the residual risk is a human toggling it on in a pipeline that publishes logs. Prohibit it in CI by policy and review.
  • False positive on legitimate drift — local-only keys intentionally absent from .env.example; maintain an ignore-list of key prefixes.
  • Config schema churn — additional_files → files already broke once; a committed config is a small ongoing liability.
  • Framework upgrade breakage — install failure or command-not-found after a Laravel/PHP bump; low blast radius at require-dev, but it blocks local setup for the whole team at once.

Ramp-up. Near zero for developers — one command, self-describing output, masked by default, slightly more setup than 1.x because of the published config. Cost still concentrates in the owner decision: the compatibility spike, the fork-versus-reimplement call, and the CI blocking policy. Budget two to three engineer-days end to end for the recommended reimplementation path — unchanged, and the delta versus forking is now smaller in features but larger in risk, since forking 2.0.0 means porting a Laravel 7-era parser to the current framework before you can use any of it.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core