The key distinction is that Composer will only install require-dev
dependencies for the "root package" – the directory where you run composer install
. The documentation describes this as:
The root package is the package defined by the composer.json
at the
root of your project. It is the main composer.json
that defines your
project requirements.
…and the require-dev
documentation specifies that it is "root-only".
In practice, this means that a package's require-dev
dependencies aren't used if the package is being installed as a dependency for something else (ie it's installed to another project's vendor
folder).
So if you have phpunit
in the require-dev
list for YourProject, and I clone down YourProject and run composer install
in the yourproject/
directory, Composer will install phpunit
to yourproject/vendor/
, because it's likely I'm doing some development on YourProject. As part of doing development I'll probably want to run YourProject's test suite, and to do that I'll need phpunit
.
But, if I add YourProject as a dependency of MyProject, installing the myproject
package will install the yourproject
package as well, but it will not install phpunit
.
You can override this behaviour with the --dev
and --no-dev
options, but the default behaviour is based on whether the package concerned is the root package.