I love composer. It is really a great tool for managing dependencies. But as I work with some uninitiated people, they never know what to do : composer install or composer update ?

I will try to explain what each command does and when to use it.

TL; DR

Run composer install when you get a new composer.lock file from your Version Control System. use  composer install  if you are working on your repository.

Run composer update when you want to checkout new versions of dependencies.

 

Let’s start our project

Imagine we have those projects:

  • foo
  • bar

Let’s start the website project, requiring foo and bar .
We will have a composer.json like this in website :

 

When you start your website project, you do not have any other composer file, so you run composer update (because composer install will throw you an error indicating that the composer.lock is missing).

The update command will try to find the highest matching version of all dependencies.

Let’s say that mapado/foo is a quite new project and has the following version number:

  • 1.0.0
  • 1.0.1
  • 1.1.0
  • 1.1.1

And mapado/bar is an older project and has those version number:

  • 1.0.0
  • 1.1.0
  • 1.1.1
  • 1.2.0
  • 2.0.0
  • 2.0.1

The composer update command will look at mapado/foo: 1.* version, so all of our 4 versions matches, he will checkout the 1.1.1 (if every other dependencies requiring mapado/foo allow this version number, ie. if mapado/bar requires mapado/foo: 2.* , you will have a lots of errors in the console output, and if it requires mapado/foo: 1.0.* , only the 1.0.1 and 1.0.0 versions will match).

It will also look at mapado/bar: 1.* . The highest matching version there is the 1.2.0 .

Composer will now write the composer.lock file, containing only the download url for the mapado/foo: 1.1.1 and the mapado/bar 1.2.0 version.

At this moment, you can run composer update or composer install , nothing will change (and nothing will get updated since no changes have been made).

Now some time passes and we release a new version for mapado/foo , the 1.2.0 .

There is the difference

If you type composer install , it will look into the composer.lock and download the fixed version in it, so it will download mapado/foo: 1.1.1 and mapado/bar: 1.2.0 (because that is the versions number fixed in the lock file).

If you type composer update , he will start again: mapado/foo: 1.* , 5 version are matching, I will checkout the last one, so 1.2.0 it is. mapado/bar: 1.* , oh, I’ve already downloaded the last known version, so I do nothing.

And that’s all !

In other words: composer update transform the composer.json file into a composer.lock with locked version. composer install downloads the locked version from the composer.lock .

You can also imagine that composer update first re-generate the composer.lock file, and then trigger composer install (which is not exactly what appends but it is easier to remember this way).

Where the misunderstanding come from

If you work alone on a simple project, you don’t really have to thing about those differences, as  composer install  will never do anything, you will always type  composer update  to update your dependencies.

But if you work in a team, someone updating the dependencies will commit the composer.lock file onto your Version Control System (even if the  composer.json  has not been changed). You will checkout a modified composer.lock file, and generally, as you do not know what to do, you will use composer update , just in case… But that is not the right way.

Final tips

Run  composer update mapado/foo  if you want to update only  mapado/foo  and its dependencies.

rm -rf vendor/mapado/foo  and composer update mapado/foo --prefer-source if you want to use git clone instead of a simple download. This way you can work on your dependencies in your vendor directory.

 

Photo: Colburn Orchestra with Gustavo Dudamel taken from laphil.com