PHPackages                             rgarciar1931/vendor-patches - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [CLI &amp; Console](/categories/cli)
4. /
5. rgarciar1931/vendor-patches

ActiveComposer-plugin[CLI &amp; Console](/categories/cli)

rgarciar1931/vendor-patches
===========================

Framework-agnostic CLI and Composer plugin to apply, revert and track the status of git patches against vendor/ dependencies in any PHP project.

v0.9.0(1mo ago)110↓66.7%MITPHPPHP ^8.1

Since Jul 17Pushed 1mo agoCompare

[ Source](https://github.com/rgarciar1931/vendor-patches)[ Packagist](https://packagist.org/packages/rgarciar1931/vendor-patches)[ Docs](https://github.com/rgarciar1931/vendor-patches)[ RSS](/packages/rgarciar1931-vendor-patches/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (1)Dependencies (8)Versions (2)Used By (0)

vendor-patches
==============

[](#vendor-patches)

A framework-agnostic Composer CLI and plugin to apply, revert, and track the status of `git apply`-based patches against `vendor/` (or any other) files in a PHP project — including dependency ordering and a transactional apply command.

Why
---

[](#why)

Third-party dependencies sometimes need a local hotfix before an upstream release is available. Keeping those hotfixes as plain `.patch` files, applied by hand, doesn't scale: there's no record of what's applied, no ordering between patches that depend on each other, and no safe way to apply "all of them" without risking a half-patched tree if one fails partway through. `vendor-patches` formalizes that workflow with a small JSON manifest and three CLI commands.

Installation
------------

[](#installation)

```
composer require rgarciar1931/vendor-patches
```

This installs the `vendor-patches` binary at `vendor/bin/vendor-patches` and registers a Composer plugin that applies any pending patches automatically after `composer install`/`update`(see [Auto-apply configuration](#auto-apply-configuration) to disable or tune this).

Quick start
-----------

[](#quick-start)

1. Create a manifest at `patches/patches.json` in your project root:

    ```
    {
      "patches": [
        {
          "id": "curl-100-continue-status",
          "name": "Fix cURL 100-continue real HTTP status",
          "description": "Corrects HTTP status parsing when a server replies with an interim 100-continue header.",
          "type": "fix",
          "sortOrder": 10,
          "dependencies": [],
          "file": "curl-100-continue-real-status.patch",
          "target": ".",
          "strip": 1
        }
      ]
    }
    ```
2. Put the corresponding `.patch` file next to it (`patches/curl-100-continue-real-status.patch`), generated the normal way with `git diff` (or `git diff --no-index`) so it has standard `a/`/`b/`path prefixes.
3. Check status, apply, and revert:

    ```
    vendor/bin/vendor-patches patch:status
    vendor/bin/vendor-patches patch:apply --all
    vendor/bin/vendor-patches patch:revert curl-100-continue-status
    ```

Commands
--------

[](#commands)

### `patch:apply [ids...] [--all] [--no-cascade] [--yes] [--manifest=] [--project-root=]`

[](#patchapply-ids---all---no-cascade---yes---manifest---project-root)

Applies one, several, or (`--all`) every patch, in dependency order.

- If a requested patch depends on one that isn't applied yet, it's automatically pulled into the plan and applied first. Pass `--no-cascade` to instead fail fast, naming the missing dependency.
- **Transactional**: if any patch in the plan fails (a real `git apply` failure, or a detected conflict), everything applied earlier in that same run is immediately reverted, in reverse order, before the command exits non-zero. A failed run never leaves the tree partially patched.
- Prompts for confirmation with the full expanded plan before touching anything, unless `--yes`is passed or the session isn't interactive.

### `patch:revert [ids...] [--all] [--no-cascade] [--yes] [--manifest=] [--project-root=]`

[](#patchrevert-ids---all---no-cascade---yes---manifest---project-root)

Reverts one, several, or (`--all`) every applied patch.

- If a requested patch has applied dependents, they're automatically reverted first (cascade). Pass `--no-cascade` to instead fail fast, naming the blocking dependent.
- Unlike `patch:apply`, a failure here is reported per-patch rather than triggering a rollback (reverting is already the "undo" operation) — but any patch that transitively depends on a failed one is skipped rather than reverted, to avoid leaving a dependent applied on top of a reverted prerequisite.

### `patch:status [--type=] [--manifest=] [--project-root=]`

[](#patchstatus---type---manifest---project-root)

Shows every patch's live status (`applied`, `not_applied`, or `conflict`), computed fresh each run via `git apply --check` / `--check --reverse` — nothing is cached or persisted, so status is always accurate even if a patch was applied or reverted outside this tool. `--type` filters by the patch's `type` field.

Manifest schema
---------------

[](#manifest-schema)

Default location: `patches/patches.json` in the project root (configurable, see below). See [`resources/manifest.schema.json`](resources/manifest.schema.json) for the full JSON Schema.

FieldTypeRequiredDefaultMeaning`id`stringyes—Unique id, `^[a-z0-9][a-z0-9._-]*$`. Used on the CLI and as the dependency-graph key.`name`stringyes—Short human title.`description`stringno`""`Longer free-text explanation.`type`stringno`"fix"`Free-form category (`fix`, `security`, `performance`, `compatibility`, ...).`sortOrder`integerno`0`Tiebreaker within the dependency-respecting order.`dependencies`string\[\]no`[]`Ids of other patches that must be applied first.`file`stringyes—Path to the `.patch` file, relative to the manifest's own directory.`target`stringno`"."`Base directory (relative to the project root) used as the `cwd` for `git apply`.`strip`integerno`1`The `-p` level passed to `git apply`.Auto-apply configuration
------------------------

[](#auto-apply-configuration)

The Composer plugin runs `patch:apply --all` non-interactively after `composer install`/`update`. Configure it via environment variables (highest precedence) or `extra.vendor-patches` in your project's `composer.json`:

```
{
  "extra": {
    "vendor-patches": {
      "auto-apply": true,
      "manifest": "patches/patches.json",
      "strict": false
    }
  }
}
```

SettingEnv var`extra.vendor-patches` keyDefaultMeaningAuto-apply`VENDOR_PATCHES_AUTO_APPLY``auto-apply``true`Whether the plugin runs at all.Manifest path`VENDOR_PATCHES_MANIFEST``manifest``patches/patches.json`Manifest location, relative to the project root (or absolute).Strict`VENDOR_PATCHES_STRICT``strict``false`Whether a failed auto-apply aborts `composer install`/`update` (non-zero exit) or just warns and continues.Env vars accept `1/true/on/yes` or `0/false/off/no` (case-insensitive). Manual CLI usage always works regardless of these settings — they only gate the automatic post-install/update hook.

If no manifest file exists at the resolved path, the plugin silently does nothing.

Requirements and known limitations
----------------------------------

[](#requirements-and-known-limitations)

- Patches must be standard `git diff`/`git format-patch`-style unified diffs with `a/`/`b/` path prefixes — raw `diff -u` output without those prefixes won't apply even if content-equivalent.
- `target` must be inside a git working tree; there's no fallback (e.g. a plain `patch` CLI driver) for non-git directories in this version.
- Only tested on Linux/macOS; Windows should work via Symfony Process but isn't CI-verified yet.
- Manifest and patch files are only ever read locally — this tool never fetches patch content from a remote source.

Development
-----------

[](#development)

```
composer install
composer test        # PHPUnit (unit + integration)
composer phpstan      # Static analysis (level 6)
composer cs-check     # PHP CS Fixer, dry-run
```

License
-------

[](#license)

MIT, see [LICENSE](LICENSE).

###  Health Score

36

—

LowBetter than 79% of packages

Maintenance90

Actively maintained with recent releases

Popularity9

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity32

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

46d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/296995245?v=4)[rgarciar1931](/maintainers/rgarciar1931)[@rgarciar1931](https://github.com/rgarciar1931)

---

Top Contributors

[![rgarciar1931](https://avatars.githubusercontent.com/u/296995245?v=4)](https://github.com/rgarciar1931 "rgarciar1931 (4 commits)")

---

Tags

plugincomposerclivendorpatchgit-apply

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/rgarciar1931-vendor-patches/health.svg)

```
[![Health](https://phpackages.com/badges/rgarciar1931-vendor-patches/health.svg)](https://phpackages.com/packages/rgarciar1931-vendor-patches)
```

###  Alternatives

[composer/composer

Composer helps you declare, manage and install dependencies of PHP projects. It ensures you have the right stack everywhere.

29.6k203.2M3.5k](/packages/composer-composer)[phpro/grumphp

A composer plugin that enables source code quality checks.

4.3k17.4M1.1k](/packages/phpro-grumphp)[drupal/core

Drupal is an open source content management platform powering millions of websites and applications.

19468.5M2.0k](/packages/drupal-core)[matomo/matomo

Matomo is the leading Free/Libre open analytics platform

21.8k40.0k](/packages/matomo-matomo)[drupal/core-recommended

Locked core dependencies; require this project INSTEAD OF drupal/core.

7544.4M464](/packages/drupal-core-recommended)[shopware/core

Shopware platform is the core for all Shopware ecommerce products.

605.9M717](/packages/shopware-core)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
