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

Composer Normalize Laravel Package

ergebnis/composer-normalize

A Composer plugin that normalizes composer.json, sorting and formatting it consistently so contributors don't argue over style. Install it as a dev dependency, allow the plugin, and run it locally or in CI to keep JSON clean and reduce merge conflicts.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

ergebnis/composer-normalize is a Composer plugin, not a Laravel package. It ships no service provider, no config publish, no facades, and no autoload surface — it registers a NormalizePlugin with Composer's plugin API and exposes a single composer normalize command. For a Laravel codebase this places it squarely in the developer toolchain layer alongside Pint, PHPStan, and php-cs-fixer, with zero production runtime footprint. That is its main architectural virtue: adopting it changes nothing about how the application boots or resolves dependencies, only the byte-level formatting of composer.json.

It is framework-agnostic and applies uniformly to Laravel applications, first-party packages, and split/monorepo sub-packages — each with its own composer.json. There is no Laravel-specific behavior to integrate against, which also means there is no Laravel-specific value beyond formatting hygiene.

Integration feasibility

Low effort, but two non-obvious gates:

  1. allow-plugins consent. Composer 2.2+ requires explicit opt-in (composer config allow-plugins.ergebnis/composer-normalize true). In non-interactive CI this must be pre-seeded in the repo, or installs prompt/fail. This is a per-repo change, not a one-time org setting.
  2. Config precedence inversion. Indentation can be set via extra.composer-normalize in composer.json or via --indent-size/--indent-style, and the extra block always overrides CLI flags. Teams expecting CI flags to win will be surprised. Governance implication: formatting policy lives in the repo, not in the pipeline definition.

A PHAR/Phive install path exists as an escape hatch where plugin allowlisting is disallowed or undesirable.

Technical risk

Overall low, with three items worth naming:

  • Semantic-safe, diff-noisy. Normalization reorders keys into canonical order, sorts package lists, and standardizes indentation — no dependency changes. But first adoption produces a large, single-purpose diff that conflicts badly with long-lived feature branches. Treat as a coordinated "format the world" commit.
  • Lock-file coupling. The command checks that composer.lock is current and updates the content-hash after rewriting. In repos where the lock is frequently stale or gitignored, this can cause confusing failures; --no-check-lock / --no-update-lock mitigate but weaken the guarantee.
  • Supply-chain surface. A plugin executes inside Composer with install-time privileges. allow-plugins is the control point — this needs a deliberate allowlist decision and a version pin, not an incidental require --dev.

Key questions

  • Which Composer major/minor versions must be supported, and is the plugin API stable across them?
  • Does normalization preserve unknown/custom top-level keys and the full extra subtree (including extra.laravel.providers and extra.branch-alias) without altering values?
  • Will reordering break any internal tooling that regex- or offset-parses composer.json (release scripts, CI matrices, version bumpers)?
  • Is the plugin allowlist centrally managed (policy) or per-repo (drift)?
  • Data-quality flags: Dependents: 0 is implausible for a 1,128-star package and likely a Packagist metric gap; the 2026-10-29 last-release date is in the future relative to normal reporting. Both should be re-verified against Packagist before any dependency-policy sign-off.

Integration Approach

Stack fit

Layer Fit Notes
Application runtime None No service provider, no autoload, no config
Composer resolution Passive Reads/writes composer.json, updates lock hash
Dev toolchain Strong Sits beside Pint, PHPStan, php-cs-fixer, GrumPHP/CaptainHook
CI Strong --dry-run returns exit 1 on drift — a clean gate
Scaffolding Strong One line in new-project skeletons prevents drift at source

Migration path

  1. Inventory. Enumerate every composer.json — root, packages/*, workbench, any split-repo definitions.
  2. Preview. Run composer normalize --dry-run --diff per repo to size the change; sanity-check that no semantic deltas appear (only ordering/indentation).
  3. Pilot. One low-traffic repo, as a standalone commit containing nothing but normalization. Add the SHA to .git-blame-ignore-revs if the org uses it.
  4. Codify. Pin indentation in extra.composer-normalize (typical Laravel convention: indent-size: 4, indent-style: space) so local and CI agree.
  5. Enforce. Wire composer normalize --dry-run into CI, advisory first, then required.

Compatibility

Composer 2.x is the realistic floor (the allow-plugins flow it documents is 2.2+). Confirm coexistence with other Composer plugins already in the fleet — composer-unused, composer-require-checker, symfony/flex-style plugins — since plugin load order and command namespacing can interact. Run the pilot with the full plugin set present, not a stripped repo.

Sequencing

Normalize before any large dependency-refresh initiative, never during one. Doing both in the same window turns a clean ordering diff into an unreviewable mixed change and makes the lock hash churn impossible to attribute. Ideal order: adopt formatter → normalize all repos → freeze → then proceed with version upgrades.

Operational Impact

Maintenance

Dev-only scope means no CVE-response obligation on production images — a broken release degrades a formatting check, not the application. The real maintenance cost is policy maintenance: the allow-plugins allowlist, the pinned version, and the extra indentation convention must stay consistent across every repo. Drift here is silent — CI passes, formatting differs.

Support

Documentation is above average for the ecosystem: README covers install (Composer/PHAR/Phive), all flags, and CI usage; changelog and releases are maintained. Exit-code semantics are documented, which matters more than prose quality for a CI gate. Fallback paths (PHAR, Phive) mean the team is never fully blocked by a plugin-policy decision.

Scaling

Negligible. Cost is O(1) per composer.json — milliseconds. The only scaling concern is breadth: a monorepo with N packages needs N invocations (or a looped CI step), since the file argument targets one path at a time. Budget a small scripting wrapper, and expect CI wall-clock impact to be immeasurable.

Failure modes

Failure Symptom Mitigation
Plugin not allowlisted command not found / install prompt hangs in CI Pre-seed allow-plugins in repo composer.json
Unnormalized file CI exit 1 with diff Expected; fix locally or via auto-run
Stale/missing lock Command refuses or hash updates unexpectedly --no-check-lock / --no-update-lock, or fix lock hygiene
extra vs CLI conflict --indent-size silently ignored Document that extra wins; avoid passing flags
First-run mega-diff Merge conflicts across active branches Single-purpose commit, coordinated window
Composer major bump Plugin API break Pin minor; test in pilot repo first

Ramp-up

Effectively zero for individual engineers — one command, and the output is self-explanatory. The actual effort is organizational, not technical: ~1 day to inventory repos, decide the allowlist and indentation convention, pilot, and land the CI gate. Plan the rollout as a governance task owned by platform/DevEx, not a feature task assigned to an application team — the value only materializes when every repo enforces the same rule.

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.
taras-koval/laravel-starter
ssofy/laravel
datalogix/laravel-error-pages
pushinbr/pam-octane
9in/laravel-server
9in/laravel-events
9in/laravel
pushinbr/pam-laravel
derian-cordoba/laravel-ab-testing
boring-o11y/unique-job-middleware
boring-o11y/httptheus
ympact/laravel-icon-registry
mattapril/laravel-responsable-reports
edlugz/tanda
daikazu/social-links
hwkdo/intranet-app-packtrack
coloredcow/laravel-audit
ironflow/halo-ui
norialabs/ledger
yangusik/thrun-laravel