Safely edit a third party composer (vendor) package in Laravel & prevent losing customized changes on release of a new version of the package

The simple, fast and safe method:

  1. Create a directory in the Laravel's root directory and name it packages or whatever you like.
  2. Move the modified package from vendor directory to your packages directory.
  3. Update composer.json to load the package from your packages directory instead of vendor directory.

first remove it from require

"require": {
    "php": ">=5.6.4",
    "laravel/framework": "5.3.*",
    "laravelcollective/html": "^5.3.0", <==== remove this line                           
    "barryvdh/laravel-debugbar": "^2.3",
    "doctrine/dbal": "^2.5"
},

and then add it to autoload

"autoload": {
    "psr-4": {
        "App\\": "app/",
        "Collective\\Html\\": "packages/laravelcollective/html/src", <==== add this line
    },
}

Please do not forget to run

composer dumpauto

Alternative for step 3.

There is also a new alternative if you're using latest version of composer.

Add this to you composer.json

"repositories": [
    {
        "type": "path",
        "url": "./packages/laravelcollective"
    }
]

And then modify the version of package to dev-master

"require": {
    "php": ">=5.6.4",
    "laravel/framework": "5.3.*",
    "laravelcollective/html": "dev-master", <==== this line                           
    "barryvdh/laravel-debugbar": "^2.3",
    "doctrine/dbal": "^2.5"
},

Finally

composer update

It actually isn't safe to edit composer packages, for the very reason you point out.

What I do is extends the classes that I want/need to change.

I have done it here with the Filesystem class. It doesn't ensure that it won't break, but it does let you update without overwriting your changes.

config/app.php

<?php

return [

    'providers' => [

//        'Illuminate\Filesystem\FilesystemServiceProvider',
        'MyApp\Filesystem\FilesystemServiceProvider',
    ],

    'aliases' => [
        ...
    ],

];

MyApp\Filesystem\FilesystemServiceProvider.php

<?php namespace MyApp\Filesystem;

use Config;
use Storage;
use League\Flysystem\Filesystem;
use Dropbox\Client as DropboxClient;
use League\Flysystem\Dropbox\DropboxAdapter;
use Illuminate\Filesystem\FilesystemManager as LaravelFilesystemManager;

class FilesystemManager extends LaravelFilesystemManager{

    public function createDropboxDriver(array $config)
    {
        $client = new DropboxClient($config['token'], $config['app']);

        return $this->adapt(
            new Filesystem(new DropboxAdapter($client))
        );
    }
}

if you want to keep your changes AND update the package from the original repo at the same time, you can fork this package and point composer to pull from your fork, not the original repo.

All you have to do is add your fork as a repository and update the version constraint to point to your custom branch. Your custom branch name must be prefixed with dev-.

update your composer.json file as follows:

{
    "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/MyGithub/html"
        }
    ],
    "require": {
        "laravelcollective/html": "dev-bugfix"
    }
}

Note that you don't change the require statement except to specify your bugfix branch. You still reference the upstream package (laravelcollective/html), not your personal fork (MyGithub/html).

also, note that dev- is automatically added so branch name is bugfix not dev-bugfix. if you named your branch as dev-bugfix you will require it as dev-dev-bugfix.