By Greg Nowak. Last updated 2026-10-03.
A tidy composer.json makes dependency decisions easier to review. If package lists change order and formatting varies between contributors, a routine update can create a noisy pull request. The team then has to work harder to spot the change that matters.
For an owner or operations lead, the benefit is a clearer record of what changed before a release. For developers and agency teams, it means fewer formatting discussions during maintenance and handover. Composer Normalize gives the file a consistent structure, while Composer’s own commands handle package sorting and validation.
Give each tool a clear job
These checks overlap less than their names suggest. Use them together, then make the result part of the project’s normal review process.
| Need | Tool | What a reviewer gets |
|---|---|---|
| Order packages added with Composer | config.sort-packages |
Readable dependency lists in future edits |
| Standardize the whole manifest | composer normalize |
Consistent structure and formatting |
| Check the manifest and lock file | composer validate --strict |
Errors and warnings surfaced before merge |
| Catch formatting drift in CI | composer normalize --dry-run |
A failing check and diff, without rewritten files |
Install the plugin with explicit trust
Composer plugins can execute code during Composer runs. Review the package before allowing it, and record permission for this specific plugin in the project configuration. Setting that permission before installation also makes the decision explicit for unattended environments.
composer config allow-plugins.ergebnis/composer-normalize true
composer config sort-packages true
composer require --dev ergebnis/composer-normalize
composer normalize
composer validate --strictThe first two commands update the shared composer.json. The third adds the normalizer as a development dependency. Run the final commands locally, inspect the diff, and commit the resulting manifest and lock file together. Avoid a blanket allow-plugins: true: it grants every Composer plugin permission to run.
Package sorting applies when Composer’s require command adds packages. It does not standardize every section someone edits by hand. Composer Normalize handles that broader cleanup, including structure and formatting. Neither tool decides whether a package belongs in the project.
Make CI check the committed result
Once the initial cleanup has been reviewed, run the checks in a job that installs development dependencies, so the plugin’s command is available:
composer install --no-interaction
composer normalize --dry-run
composer validate --strictThe dry run reports a diff and fails when the manifest needs normalization or the lock file is out of date; it does not rewrite repository files in CI. A contributor can run composer normalize locally and commit the correction. Strict validation also makes warnings fail the job. For a private application, read those warnings before enforcing the rule: some concern metadata used when publishing a package, while others reveal a problem worth fixing.
Keep this check in a development or pull request job. A production install commonly omits require-dev, so it should not be expected to provide the normalizer command.
Review the lock file deliberately
For an application, commit composer.lock so CI and other contributors install the resolved versions. Composer Normalize checks an existing lock file and updates its content hash when normalization requires it. Inspect that change alongside composer.json; do not assume a lock-file diff means package versions changed. Composer’s lock-file guidance explains why keeping it in version control matters.
The plugin offers --no-update-lock and --no-check-lock for workflows with a specific reason to use them. They are poor default CI settings because they can conceal a mismatch. A library may choose not to commit a lock file; document that choice so the team knows which file CI is expected to check.
Use the cleaner file to ask better questions
Normalization makes policy decisions visible; it cannot make them for you. During the first review, check whether test tools sit in require-dev, PHP and extension requirements match the environment that runs the application, and old integrations have left unnecessary packages behind. Look at custom repositories and Composer scripts too: each should have a clear purpose and owner.
If the project uses a config.platform override, confirm that it reflects the intended deployment target. Where you can check the actual server or build image, composer check-platform-reqs --no-dev checks installed PHP and extensions against the installed packages without relying on that override. This is a separate environment check, not something a formatter can infer.
Roll out the change in one focused pull request
On an established project, make the first normalization a dedicated pull request. Keep dependency upgrades, changed PHP constraints and script changes for separate reviews. The initial diff may be large, but reviewers can then approve a clear formatting baseline. Later pull requests should make package decisions easier to spot.
For agencies maintaining several PHP sites, put the same commands in repository templates and handover notes. If dependency maintenance and release checks keep slipping between teams, Greg can help establish a delivery workflow people can follow.
Related on GrN.dk
- Google Review Link Generators: What Small Teams Actually Need
- NGINX Can Read JSON Before Routing—Should It Handle Your AI API?
- AI automations need a spend dashboard before the first runaway bill
Need help with this kind of work?
Discuss your PHP delivery workflow with Greg Get in touch with Greg.