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

Vendor Patches Laravel Package

symplify/vendor-patches

Symplify Vendor Patches generates vendor patches for your Composer packages with a single command. Copy a vendor file with a .old suffix, edit the original, then run generate to create patch files and auto-configure cweagans/composer-patches.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

  • Unblocking a release on a third-party defect. When a dependency ships a bug that breaks your app (PHP 8.4 deprecation, null-safety regression, an upstream fix merged but unreleased), this package turns "wait for the maintainer" into a one-day decision. You ship a pinned, reviewable diff instead of blocking the roadmap or forking the library.
  • Build vs. buy vs. fork vs. wait. This package makes the middle option cheap: you are not vendoring a fork (ongoing merge debt, no upstream relationship), and you are not waiting (schedule risk). It's the lowest-commitment way to buy time, which means it's usually the correct first answer before a fork is justified.
  • Prioritizing upstream contribution work. Every generated patch is a visible, dated artifact of a gap in someone else's package. A patch directory is an objective backlog of "PRs we owe upstream" — useful for arguing for engineering time on open-source contribution, and for tracking how long you've been carrying each workaround.
  • Scope decisions on framework-level customization. A patch is an admission that the extension points ran out. Having a cheap fallback raises the bar for patching: if a ServiceProvider hook, container binding, Macroable, or Model::resolveRelationUsing can do it, you don't patch. This package supports a defensible "configure first, patch last" policy without forcing a rewrite when the policy fails.
  • Dependency and upgrade policy. Patch count per package becomes a health metric for your dependency portfolio. A package you patch every minor release is a package you should be evaluating for replacement — that's a roadmap input, not just a maintenance chore.
  • Deployment and environment decisions. The install model forces an explicit decision: is cweagans/composer-patches a production dependency or not? For Laravel shops on Forge/Envoyer/Vapor/Cloud running composer install --no-dev, it must be a real require, which is a procurement/compliance and build-pipeline conversation, not just a dev-tooling one.
  • Vendor-risk decisions on private and internal packages. The --resolve-from-directory and --patches-file options let you patch packages installed from private VCS or path repositories, or keep the patch map in a separate reviewable artifact — both relevant when you're maintaining internal shared packages across multiple Laravel apps.
  • Not supported: feature work, runtime behavior toggles, or anything customer-facing. This is a dev-time, deploy-time tooling decision. It should never appear on a product roadmap; it appears on an engineering-enablement or release-readiness one.

When to Consider This Package

Adopt when all of these hold:

  • You have a concrete, reproduced defect or missing behavior in a third-party package, and no release containing the fix is available on your timeline.
  • The change is small and local — a few lines in one or two files. Patches scale badly past that.
  • You can open (or have opened) an upstream PR. A patch with no upstream path is a fork in disguise and should be treated as such.
  • Your deploy pipeline does a real composer install rather than promoting a cached vendor/ artifact. If you cache vendor/ between CI jobs, the patch model quietly breaks.
  • Someone owns the patch lifecycle: re-validating after every bump of the patched package, and removing the patch when upstream ships.

Look elsewhere when:

  • You need a patch manager. This package is a patch generator. Application, ordering, conflict handling, and lockfiles are all cweagans/composer-patches. Evaluate that dependency on its own merits — it's the one that runs in production.
  • The change is large or structural. Multiple files across multiple packages, or anything resembling a rewrite, is a fork or a replacement decision, not a patch.
  • The package is abandoned or unmaintained. Patching something nobody fixes is a permanent tax. Replace it.
  • You can configure it instead. Framework hooks, service container overrides, Macroable, model relation resolvers, published config, or a thin adapter/wrapper around the dependency will always beat a patch on upgrade cost.
  • Your team can't absorb the drift cost. Every dependency bump touching a patched package is a potential Hunk #N FAILED on composer install, diagnosed with -vvv and fixed by hand. If nobody has budget for that, the patch becomes an outage waiting for a routine upgrade.
  • You're on macOS without GNU patch. BSD patch can hang applying patches; gpatch via Homebrew is a hard prerequisite on developer machines. Small, but it's a real onboarding friction item.
  • You need ecosystem validation as a procurement signal. 192 stars, zero dependents, and a "readme"-level maturity rating mean no third-party corroboration. This is a well-scoped single-author utility from a known figure in the PHP tooling space (Symplify/Rector), not a platform. Judge it as a script you happen to install, and be comfortable that you could replace it.
  • You're on cweagans/composer-patches v2 and haven't budgeted the migration. The workflow gains composer patches-relock and composer patches-repatch, and v1 patches starting with --- /dev/null must be rewritten to --- <file-path> or they fail with a confusing path-stripping error. That's migration work, not a drop-in.

Adoption prerequisites to confirm before saying yes: vendor/bin/vendor-patches exists after install; cweagans/composer-patches is in require (not require-dev) if you deploy with --no-dev; allow-plugins includes cweagans/composer-patches; patches/, composer.json, and composer.lock are committed together; composer update --lock is part of the documented workflow (the lock hash changes whenever extra.patches does).

How to Pitch It (Stakeholders)

For executives — one paragraph: We have a small, recurring class of problem where a third-party library has a bug we can't wait on and can't afford to fork. This tool lets us ship a reviewed, version-controlled fix in a day, roughly one command, and it disappears automatically once the vendor releases the real fix. Cost is low and reversible; the main expense is a small amount of upkeep each time we upgrade the affected package. It is a release-unblocker, not a product capability, and it should never appear in customer-facing plans.

For engineering leadership — the trade: You accept a maintenance liability (patch drift on every bump of a patched package) in exchange for schedule independence. The liability is bounded and visible — patches live in patches/, they're plain diffs, they show up in code review, and each one has an obvious exit (upstream release → delete patch → composer update --lock). The failure mode is loud, not silent: a bad patch breaks composer install before it breaks production. Mitigate by capping patch lifetime, tracking patches per package as a dependency-health metric, and requiring an upstream PR link in the commit that adds each patch.

For the engineering team — the mechanics: Install symplify/vendor-patches as a dev dependency and cweagans/composer-patches as a real dependency if you deploy with --no-dev, plus the allow-plugins entry. Then: copy the file to <file>.old (never autoloaded, so you can run the app while you work), edit the original, run vendor/bin/vendor-patches generate. On composer-patches v2, follow with composer patches-relock and composer patches-repatch, then composer update --lock, then verify with composer install --verbose from a clean tree. Commit the patch and the lockfile together. Treat patch files as source in review. Batch all edits to a package before generating — the tool keys on file path and a second run overwrites the first. Use --resolve-from-directory for private/path repositories or the patch will silently apply to nothing. On long-running processes, restart workers and reload Octane after deploying a patch.

The honest caveat to state up front: This is a generator with no manager, no dependents, and readme-level maturity. That's fine — it's a thin, auditable script — but it means the operational discipline is entirely ours. If we can't commit to owning patch revalidation and removal, we should configure around the problem or replace the dependency instead.

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.
dakiquang/laravel-oauth-refresh-lock
woda/laravel-worktrees
dalefranks/ramasite
faghy/laracashbook
roundly-consulting/google-places-for-laravel
roundly-consulting/kubernetes-api-for-laravel
roundly-consulting/plausible-for-laravel
gvp/gvp-laravel-template
metasyncsite/laravel-metasync-client
roundly-consulting/onboarding-for-laravel
andydefer/laravel-notification
adachsoft/cli-process-tester
jhaskell13/laraflow
sebastienheyd/boilerplate-media-manager
ccast/tagixo-primix
pretendtrue/laravel-builder
sawmainek/laravel-scout-tntsearch-driver
tomshaw/laravel-calendar-table
dibakar/laravel-ownership
adachsoft/changelog-linter