stolt / composer-peel
A small development tool to strip development-only metadata from Composer manifests when releasing PHP packages for distribution.
Requires
- php: >=8.2
- symfony/console: ^7.4
Requires (Dev)
- carthage-software/mago: ^1.50
- phpstan/phpstan: ^2.2
- phpunit/phpunit: ^12.5
- stolt/lean-package-validator: ^6.0
- stolt/version-aligner: ^1.0
- zenstruck/console-test: ^1.8
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
A small PHP development tool for removing configurable development-only metadata from composer.json files when releasing
packages for distribution.
Why?
A package's composer.json often contains metadata that is useful while developing and maintaining the package, but is
not needed by downstream consumers.
For example, development dependencies, development autoloading, and Composer scripts can make up a significant part of a project's development manifest.
composer-peel lets you explicitly define which Composer sections should be removed from a release manifest.
The goal is simple:
Keep the package manifest focused on what consumers need and leave development metadata behind.
What gets peeled?
The sections removed by composer-peel are configurable.
The default configuration includes the following sections:
| Section | Purpose |
|---|---|
require-dev |
Development-only dependencies |
autoload-dev |
Development-only autoloading |
scripts |
Composer scripts used during development and CI |
scripts-descriptions |
Composer scripts descriptions |
scripts-aliases |
Composer scripts aliases |
Runtime dependencies and package autoloading remain untouched.
Installation
Install composer-peel as a development dependency:
composer require --dev stolt/composer-peel
Usage
Peel the current composer.json:
composer-peel peel
Preview the changes without modifying the manifest:
composer-peel peel --dry-run
Use a custom configuration:
composer-peel peel --config=.composer-peel.php
A backup can also be created before the manifest is modified:
composer-peel peel --backup-file=.composer-unpeeled.json
Previewing changes with --dry-run
Use --dry-run to inspect what composer-peel would remove without modifying composer.json.
composer-peel peel --dry-run
The dry run shows:
- the manifest being processed,
- the configuration being used,
- the sections that would be removed,
- the original manifest size,
- the projected manifest size,
- the estimated size reduction.
With the default configuration:
composer-peel --dry-run
Manifest: composer.json
Configuration: internal defaults
Sections to be removed:
- require-dev
- autoload-dev
- scripts
Original size: 2,480 bytes
Projected size: 1,120 bytes
Estimated reduction: 1,360 bytes (54.8%)
Dry run completed. No files were modified.
The values above are illustrative. The actual result depends on the contents of your composer.json and the configured
peeling rules.
Configuration
composer-peel supports an optional PHP configuration file named .composer-peel.php in the project root.
A configuration can define which Composer sections are peeled, as well as release backup and Git commit behaviour:
<?php declare(strict_types=1); return [ 'peel' => [ 'sections' => [ 'require-dev', 'autoload-dev', 'scripts', ], ], 'release' => [ 'backup' => [ 'enabled' => true, 'path' => '.composer-unpeeled.json', ], ], 'git' => [ 'commit_messages' => [ 'before_tag' => 'chore(dist): prepare Composer manifest for release', 'after_tag' => 'chore: restore development Composer manifest', ], ], ];
Peel sections
The peel.sections option defines the top-level Composer sections that should be removed:
'peel' => [ 'sections' => [ 'require-dev', 'autoload-dev', 'scripts', ], ],
Only explicitly configured sections are peeled.
This makes the behaviour predictable and allows each package to decide which metadata belongs exclusively to its development workflow.
Release backup
The release backup stores the original composer.json before it is peeled:
'release' => [ 'backup' => [ 'enabled' => true, 'path' => '.composer-unpeeled.json', ], ],
The backup provides a recovery point if the release process fails before the original manifest is restored.
Make sure the backup file is not unintentionally included in the release.
Git commit messages
The automated release workflow uses configurable commit messages:
'git' => [ 'commit_messages' => [ 'before_tag' => 'chore(dist): prepare Composer manifest for release', 'after_tag' => 'chore: restore development Composer manifest', ], ],
before_tag is used for the commit containing the peeled manifest.
after_tag is used for the commit restoring the original development manifest.
Release workflow
composer-peel can automate the process of preparing a peeled manifest for a Git-tagged release while restoring the
original development manifest afterwards.
Run:
composer-peel peel v1.0.0
The workflow is:
- Back up the original
composer.json, if enabled. - Generate the peeled manifest.
- Commit the peeled manifest.
- Create the release tag.
- Restore the original manifest.
- Commit the restored manifest.
The resulting history looks like this:
Development commit
│
▼
Peeled manifest commit
│
└── Release tag (v1.0.0)
│
▼
Restored development manifest commit
The release tag therefore points to the peeled manifest, while the development branch continues with the original manifest.
Important
The automated release workflow only works when the peeled-manifest commit does not need to pass the project's normal development CI checks.
After peeling, development dependencies, development autoloading, and Composer scripts may no longer be available. CI jobs that depend on them can therefore fail.
If your release process requires CI validation of the tagged commit, consider using composer-peel as a separate
distribution/build step instead of tagging the peeled manifest directly.
License
This CLI and its library are licensed under the MIT license. Please see LICENSE.md for more details.
Changelog
All noteworthy changes are documented in the CHANGELOG.md.
Contributing
If you're considering contributing to this project, have a look at this repository's CONTRIBUTING.md for more advice.
