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 Cleanup Plugin Laravel Package

barryvdh/composer-cleanup-plugin

Composer plugin that cleans up your vendor directory by removing unnecessary files such as tests, documentation, and examples from installed packages, keeping your deployment lean and reducing disk usage without affecting runtime behavior.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

What it is (and isn't). barryvdh/composer-cleanup-plugin is a Composer lifecycle plugin, not a Laravel package. There is no service provider, no config/ publish, no container bindings, no runtime footprint. It hooks Composer's post-package-install / post-package-update events and deletes dev-only files (tests, docs, examples, PHPUnit configs, CI metadata, .git) from each package after it is unpacked into vendor/. The correct TPM frame is build-artifact optimization, governed with the same rigor as a Dockerfile directive or a CI shell script — not as a platform dependency with a support contract.

Architecture fit: Weak but bounded. It touches exactly one phase of the delivery pipeline — deployment packaging — and no architectural layer of the application. It informs no product, roadmap, or user-facing decision. The entire business case reduces to one question: is there a measured, hard artifact-size constraint we are currently violating? Candidates are real but narrow: serverless (Lambda/Cloud Run) package ceilings, container image size and registry storage/egress billing, air-gapped or bandwidth-constrained distribution, and CI cache-size limits. Where composer install --no-dev --prefer-dist --optimize-autoloader plus a multi-stage build already clears the constraint, this plugin buys marginal bytes in exchange for install-time code execution.

Integration feasibility: Technically trivial, organizationally gated. It is a require-dev line in the root project, a config.allow-plugins entry, and an extra.cleanup.rules block (a * default with narrow per-package overrides). Three reviews — not engineering effort — determine feasibility:

  • Security: install-time code execution from an archived, zero-dependent package.
  • Legal/compliance: blanket *.md / docs/ rules strip LICENSE* and attribution text that SBOM or open-source obligations may require in the shipped artifact.
  • Platform: whether an archived plugin sets the precedent for the org's allow-plugins allowlist.

Technical risk: Medium-to-high and asymmetric — the downside is a broken or silently ineffective build, the upside is tens of megabytes. Dominant failure modes:

  • Silent no-op. Composer 2.2+ blocks plugins without an allowlist entry; in non-interactive CI the plugin is skipped and the build still reports success. Equally common: security-hardened CI images pass --no-plugins globally, which disables cleanup while every log line looks clean.
  • Over-broad globs deleting license text, and deletion inside autoloaded PSR-4 roots interacting badly with --classmap-authoritative.
  • path repositories / --prefer-source: cleanup writes through symlinks and mutates the actual local package checkout — a shared working copy, not a throwaway artifact.
  • No patch path. Archived, last release 2023-08-05, 144 stars, zero dependents. A future Composer or PHP major breaks it and nobody upstream fixes it; if it matters, we fork it.

Note also what it does not save: the dist archives are still downloaded and cached in full, so install bandwidth and Packagist egress are unchanged. Savings are on-disk/in-artifact only.

Key questions:

  • What is the baseline versus post-cleanup delta — vendor bytes, file count, image size, artifact size, build seconds — on one representative service?
  • Which Composer 2.x and PHP versions are validated, and what is the migration cost if Composer's plugin API shifts?
  • Do the rules support negation/exclusion so LICENSE* and autoload roots can be protected?
  • Is it verified compatible with --no-dev, --prefer-dist, --optimize-autoloader, --classmap-authoritative, and --no-scripts (which does not disable plugins)?
  • Are path repositories or symlinked packages anywhere in the build matrix?
  • Does any post-install-cmd / post-autoload-dump script touch files the plugin removes?
  • Is the resulting vendor/ tree deterministic across clean installs and machines?
  • Who owns the fork, and is composer install --no-plugins documented as the rollback lever?

Integration Approach

Stack fit: Laravel/PHP on Composer 2, confined to CI/CD image builds and release packaging. Composer loads plugins only from the root project, so adding it to a package we publish does nothing for consumers and creates confusion. Encode as policy: permitted in build pipelines as a pinned require-dev; prohibited in application require blocks; prohibited in published packages.

Migration path — evidence first, tooling second:

  1. Baseline one service. du -sh vendor, find vendor -type f | wc -l, container image size, release artifact size, build duration. No baseline, no pilot.
  2. Locate the concentration. du -sh vendor/*/* | sort -rh | head -20. On a modern Laravel app most dependencies already ship export-ignore for tests and docs, so expect a long tail in a handful of stragglers — not a jackpot.
  3. Pilot in a disposable CI branch with an exact version pin, committed lockfile, and the allow-plugins entry committed alongside.
  4. Clean install and diff. Run composer install --no-dev --prefer-dist --optimize-autoloader, then diff the vendor file manifest against baseline and confirm the delta matches expectation.
  5. Promote only if the delta is material (i.e., it changes a limit we are actually near) and every gate below passes.

Compatibility gates before promotion (all required):

  • Full test suite green after cleanup.
  • Staging smoke deploy: app boots, autoloader resolves, no missing-file fatals.
  • LICENSE* and attribution files present (or explicitly excluded by policy sign-off).
  • No path repositories or --prefer-source in the matrix.
  • Rules reviewed package-by-package against the top-20 offenders, not a blanket *.
  • CI log assertion that cleanup actually ran (guards against the silent-skip trap).

Sequencing within the build: composer install --no-dev --prefer-dist → plugin runs per package → composer dump-autoload --optimize --classmap-authoritative → application build steps. Never run cleanup after autoload optimization without re-dumping, and never place a cleanup rule over a directory the classmap scanned.

Rollback: composer install --no-plugins, or revert composer.json/composer.lock and rebuild. Both must be in the runbook before the first production build ships.

Operational Impact

Maintenance: Effectively zero upstream maintenance and non-zero internal maintenance — the worst combination to leave unowned. Assign a named platform/build owner at adoption and put a review date on the calendar. The realistic plan is a fork: budget a day to take custody and a few hours per year to rebase if Composer's plugin interface moves. Treat it as frozen, not as a supported dependency.

Support: No maintainer response, no security patch stream, no issue triage. If it breaks a build, we are the support desk. That is acceptable for a single scoped pipeline and unacceptable as an org-wide standard — an install-time plugin that can block composer install for every team simultaneously is a platform-wide single point of failure with no vendor.

Scaling: Scales fine mechanically — it adds seconds of file deletion per build and is cached inside Docker layers like any other composer install step. It scales poorly organizationally: every new service that copies the pattern inherits an archived dependency, a path-repository hazard, and a compliance question. Contain it with a documented template, a pinned version, and a written exception rather than allowing organic copy-paste adoption.

Failure modes to plan for:

Failure Symptom Mitigation
Missing allow-plugins entry Cleanup silently skipped, build green, no savings CI assertion that cleanup ran; fail the job if the delta is zero on a known-bloated dependency
CI passes --no-plugins globally Same silent no-op Explicit flag audit of the pipeline
Over-broad rules Missing license files, missing autoloaded fixtures, runtime fatals Narrow per-package rules, LICENSE* exclusion, staging smoke deploy
path repo / symlink write-through Local package checkout mutates Prohibit cleanup on any pipeline with path repos
--classmap-authoritative interaction Class-not-found at boot Re-dump autoload post-cleanup; never rule over PSR-4 roots
Composer/PHP upgrade breakage Install fails org-wide on the affected pipeline Exact pin, committed lockfile, --no-plugins escape hatch, scheduled review
SBOM/audit variance Audit tooling reports absent docs or license text Legal stance documented before rules are written

Ramp-up: Minimal for any engineer fluent in Composer — an hour to read the rules format, half a day for a competent build engineer to baseline, pilot, diff the manifest, and validate. The real ramp-up cost is organizational, not technical: getting security, legal, and platform to sign one exception, and getting the owner named. Budget roughly two engineer-days total for pilot plus validation plus runbook, and set an explicit exit criterion — replace with native flags, leaner base images, or a short deterministic CI cleanup script at the next review.

Bottom line for the TPM: do not adopt this as a standard dependency. Approve a time-boxed pilot only where a specific service is measurably over a hard artifact limit, with an exact version pin, a committed lockfile and allowlist entry, explicit LICENSE* protection, a manifest-diff and smoke-deploy gate in CI, a documented --no-plugins rollback, and a named owner with a scheduled re-review. If the delta doesn't move a real limit, ship the CI cleanup script or better Docker layering instead — same bytes, no install-time execution, nothing archived to depend on.

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.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings