Dev Dependencies
Not every package your project depends on is actually needed once the app is running live. Testing
frameworks, debugging tools, and code style checkers are useful while you're writing code, but they
have no business sitting in your production vendor/ folder. Composer keeps these two
kinds of dependencies separate using the require-dev section of composer.json.
The require-dev Section
composer.json supports a second dependency block alongside require, called
require-dev. Anything listed here is only meant for development machines — things
like test runners, static analysis tools, and debugging helpers.
{
"require": {
"monolog/monolog": "^3.0"
},
"require-dev": {
"phpunit/phpunit": "^10.0"
}
}
monolog/monolog is something the application code actually calls at runtime, so it belongs
in require. phpunit/phpunit only runs your test suite while you're developing,
so it belongs in require-dev.
Adding a Dev Dependency
Add the --dev flag to composer require to place a package into
require-dev instead of require. PHPUnit — the testing tool mentioned as
"coming soon" on the Composer HOME page — is the classic example.
composer require --dev phpunit/phpunit
Composer downloads PHPUnit into vendor/ just like any other package, but records it under
require-dev in composer.json so everyone knows it's a development-only tool.
Installing Without Dev Dependencies
When it's time to deploy to a production server, you don't want PHPUnit and other dev-only tools taking
up space or, worse, being accidentally callable from live code. Pass --no-dev to
composer install to skip everything listed under require-dev.
composer install --no-dev
This installs only the packages under require — exactly what the running application
needs, and nothing more.
Why the Distinction Matters
| Benefit | Why it matters |
|---|---|
Smaller production vendor/ folder | Faster deploys and less disk space used on the server |
| No accidental use of dev-only tools | Nobody can call a debugging helper or test utility from live request code, because it was never installed |
| Clear intent | Anyone reading composer.json can immediately tell what's runtime-critical versus developer tooling |