“Composer require local package”: Working with symlinked Composer packages in PHP

When developing a PHP library/package, you most likely also have a project on disk that consumes said library. Take a WordPress plugin for example: to test it, you need a WordPress installation — both are linked but separate projects. To speed up development you can tell Composer to use the local version of the package, instead of having to copy files from folder to folder as you develop.

~

I’m assuming a folder structure like this:

bramus in ~/repos
$ tree -L 1
.
├── my-library
└── my-project

If my-project were to use the published version of my-library, you would run the following command:

bramus in ~/repos/my-project
$ composer require author/my-library

The ~/repos/my-project/composer.json would then look as follows:

{
    // …
    "require": {
        "author/my-library": "*"
    }
}

~

During development of my-library you don’t want to be editing the copy of my-library which resides inside the my-project/vendor/… folder. What you want is to edit the local version of ~/repos/my-library directly, and make my-project use that version.

To do this, Composer allows you to configure the package sources using the repositories option of its configuration. To refer to the local copy adjust ~/repos/my-project/composer.json so that it has an entry pointing to ~/repos/my-library/:

{
    // …
    "require": {
        "author/my-library": "*"
    },
    "repositories": [
        {
            "type": "path",
            "url": "../my-library"
        }
    ]
}

With this addition, re-run the composer require command, and it’ll symlink ~/repos/my-library/ into ~/repos/my-project/vendor/author/my-library/:

bramus in ~/repos/my-project
$ composer require author/my-library

- Installing author/my-library (dev)
Symlinked from ../my-library

🐛 Not seeing this output? Try removing your vendor/ folder first, and then re-require your package. You might also need to add :dev-branchname to your requirement, e.g. composer require author/my-library:dev-master

When you now edit code inside ~/repos/my-library/, the ~/repos/my-project will also be up-to-date 🙂

💁‍♂️ You can also use repositories to refer to privately published repositories. No need to fiddle with Satis or the like

Did this help you out? Like what you see?
Thank me with a coffee.

I don\'t do this for profit but a small one-time donation would surely put a smile on my face. Thanks!

BuymeaCoffee (€3)

To stay in the loop you can follow @bramus or follow @bramusblog on Twitter.

Published by Bramus!

Bramus is a frontend web developer from Belgium, working as a Chrome Developer Relations Engineer at Google. From the moment he discovered view-source at the age of 14 (way back in 1997), he fell in love with the web and has been tinkering with it ever since (more …)

Unless noted otherwise, the contents of this post are licensed under the Creative Commons Attribution 4.0 License and code samples are licensed under the MIT License

Join the Conversation

2 Comments

  1. Or you can add to your code:

    $autoloader = include('path/to/vendor/autoload.php);
    
    if ($is_dev_env) {
        $autoloader->setPsr4(
            'Namespace\\Of\\My\\Local\\Package\\',
            'path/to/my/local/package/source'
        );
    }

    Your composer.json/.lock is then untouched.

Leave a comment

Leave a Reply to Furgas Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.