Composer and Packages
Composer is PHP's dependency manager. It downloads libraries ("packages") from Packagist, the central PHP package repository, installs the right versions of everything they depend on, and generates an autoloader so you can use any class immediately. Every modern PHP project — including Laravel and Symfony applications — is built on Composer.
Installing Composer
Follow the instructions at getcomposer.org/download: on Windows there's an installer; on macOS brew install composer works; on Linux, the download page gives a short script that verifies the installer's checksum. Afterwards:
composer --version
Composer version 2.10.3 2026-08-27 13:34:23
Adding a package
In your project folder, composer require adds a package. Here we install league/commonmark, a popular Markdown-to-HTML converter:
composer require league/commonmark
Composer creates or updates three things:
composer.json— the packages your project needs, with version constraints. You edit and commit this.composer.lock— the exact versions installed, so every developer and server gets identical code. Commit this too.vendor/— the downloaded code and the autoloader. Don't commit it; it's recreated withcomposer install.
{
"require": {
"php": ">=8.3",
"league/commonmark": "^2.7"
}
}
Then load the autoloader once at the start of your script, and every installed class is available:
<?php require __DIR__ . '/vendor/autoload.php'; use League\CommonMark\CommonMarkConverter; $converter = new CommonMarkConverter(['html_input' => 'escape']); $markdown = <<<MD # Release notes Version **2.0** brings: - faster *search* - a [new API](https://example.com/api) <script>alert('ignored')</script> MD; echo $converter->convert($markdown);
<h1>Release notes</h1>
<p>Version <strong>2.0</strong> brings:</p>
<ul>
<li>faster <em>search</em></li>
<li>a <a href="https://example.com/api">new API</a></li>
</ul>
<script>alert('ignored')</script>Note the html_input option: raw HTML in user-written Markdown is escaped, protecting against XSS (lesson 47).
Version constraints
Packages follow semantic versioning: MAJOR.MINOR.PATCH. A new major version may break compatibility; minor and patch versions shouldn't. Constraints in composer.json say which versions you accept:
| Constraint | Accepts |
|---|---|
^2.7 | 2.7.0 up to (not including) 3.0.0 — the usual choice |
~2.7.1 | 2.7.1 up to (not including) 2.8.0 |
2.7.* | Any 2.7.x |
>=8.3 | 8.3 or newer |
2.7.4 | Exactly that version (rarely a good idea) |
The everyday commands
| Command | What it does |
|---|---|
composer require vendor/package | Add a dependency |
composer require --dev vendor/package | Add a development-only dependency (tests, tools) |
composer install | Install exactly what composer.lock says — use after cloning and on servers |
composer update | Upgrade packages within your constraints and rewrite the lock file |
composer remove vendor/package | Remove a dependency |
composer outdated | List packages with newer versions available |
composer audit | Check installed packages against known security advisories |
composer dump-autoload | Regenerate the autoloader after changing autoload settings |
composer install --no-dev --optimize-autoloader | Production install: no dev packages, faster autoloading |
Autoloading your own code
Composer's autoloader works for your classes too. Map your namespace to a folder with PSR-4 (lesson 43):
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
<?php namespace App\Pricing; final class Discount { public static function apply(float $price, int $percent): float { return round($price * (100 - $percent) / 100, 2); } }
<?php require __DIR__ . '/vendor/autoload.php'; use App\Pricing\Discount; echo Discount::apply(80, 25), "\n";
60
After editing the autoload section, run composer dump-autoload (here, composer install did it).
Scripts
The scripts section defines shortcuts for common tasks, run with composer <name>:
{
"scripts": {
"test": "phpunit",
"analyse": "phpstan analyse src",
"check": ["@analyse", "@test"]
}
}
Choosing packages
Packagist (packagist.org) lists hundreds of thousands of packages. Before adding one, check that it's actively maintained, widely installed, supports your PHP version, and has a suitable licence. Some widely used ones:
| Need | Packages |
|---|---|
| Dates | nesbot/carbon |
| HTTP client | guzzlehttp/guzzle, symfony/http-client |
| Templates | twig/twig |
| Logging | monolog/monolog |
| Environment config | vlucas/phpdotenv |
symfony/mailer, phpmailer/phpmailer | |
| Testing and quality | phpunit/phpunit, pestphp/pest, phpstan/phpstan |
Every dependency is code you trust and must keep updated. Run composer audit regularly, and don't add a package for something a few lines of your own code can do.
Try it yourself
Start a project with composer init, require league/commonmark, and convert a Markdown file into HTML.