The composer.json Builder generates the manifest Composer uses to manage a PHP project’s dependencies, autoloading and scripts. Choose Laravel, Symfony or a plain library and the tool emits valid JSON with the right framework packages and dev tooling.
How it works
Composer reads composer.json to resolve packages from Packagist. The require section lists runtime dependencies — for Laravel that means laravel/framework and laravel/tinker plus a PHP constraint; for Symfony, the console and runtime components. The require-dev section holds tools like phpunit, pint or phpstan that are installed only outside production. Version constraints use the caret operator, so ^11.0 accepts any 11.x but blocks 12.0.
The autoload.psr-4 map wires a namespace prefix to a directory so Composer can locate your classes by filename. Laravel projects get the conventional App\, Database\Factories\ and Database\Seeders\ mappings; libraries get a single src/ mapping. The output is produced with JSON.stringify, so it is always valid JSON.
What each section does
| Section | Purpose | Example entry |
|---|---|---|
name | Package identifier on Packagist | "acme/my-app" |
require | Runtime dependencies | "laravel/framework": "^11.0" |
require-dev | Dev and test tooling only | "phpunit/phpunit": "^11.0" |
autoload.psr-4 | Namespace to directory map | "App\\": "app/" |
scripts | Composer lifecycle hooks | "post-install-cmd": [...] |
minimum-stability | Lowest release quality allowed | "stable" |
config | Composer behaviour settings | "optimize-autoloader": true |
Version constraint reference
Composer’s version strings follow semantic versioning conventions:
^11.0— any 11.x version, blocks 12.0 (most common choice)~11.3— 11.3.x only, blocks 11.4 (tighter patch-level pin)>=11.0 <12.0— same as^11.0written explicitly*— any version (avoid in production)dev-main— tracks the main branch directly
For new projects, caret constraints are the right default. They allow security updates and non-breaking releases to install automatically when you run composer update, without risking a major version bump.
Example: install and run
After saving the file, install dependencies:
composer install # writes composer.lock
composer install --no-dev # production: skip require-dev
composer validate # check composer.json is well-formed
composer outdated # show packages with newer versions available
Common errors and how to avoid them
Wrong package name format. Composer names must be vendor/package in lowercase. Using mixed case or omitting the slash causes the package to fail Packagist lookup and composer validate to error.
Missing PHP constraint. Always specify a PHP version constraint in require — for example, "php": "^8.2". Without it, Composer may install on a server running PHP 7 and produce cryptic runtime errors that could have been caught before deployment.
Skipping composer.lock in version control. For library packages, composer.lock is intentionally left out of version control so downstream users get the latest compatible versions. For applications and services, always commit composer.lock so every developer and every deployment installs the same resolved versions. Omitting this is one of the most common causes of “works on my machine” bugs.
Putting the wrong packages in require vs require-dev. Testing frameworks, code style checkers, and static analysers belong in require-dev. Shipping them in require inflates the production dependency tree. Running composer install --no-dev on a system where they were in require (not require-dev) pulls them anyway and bloats your production container.
Tips and notes
Commit composer.lock for applications so deployments install identical versions. Keep minimum-stability at stable with prefer-stable: true unless you deliberately need pre-release packages. The optimize-autoloader and sort-packages config keys speed up class loading and keep your require sections tidy. Run composer validate to confirm the file is well formed before committing.