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
Output
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 with composer install.
JSON composer.json
{
    "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
<?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);
Output
<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>
&lt;script&gt;alert('ignored')&lt;/script&gt;

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:

ConstraintAccepts
^2.72.7.0 up to (not including) 3.0.0 — the usual choice
~2.7.12.7.1 up to (not including) 2.8.0
2.7.*Any 2.7.x
>=8.38.3 or newer
2.7.4Exactly that version (rarely a good idea)

The everyday commands

CommandWhat it does
composer require vendor/packageAdd a dependency
composer require --dev vendor/packageAdd a development-only dependency (tests, tools)
composer installInstall exactly what composer.lock says — use after cloning and on servers
composer updateUpgrade packages within your constraints and rewrite the lock file
composer remove vendor/packageRemove a dependency
composer outdatedList packages with newer versions available
composer auditCheck installed packages against known security advisories
composer dump-autoloadRegenerate the autoloader after changing autoload settings
composer install --no-dev --optimize-autoloaderProduction 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):

JSON composer.json
{
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    }
}
PHP src/Pricing/Discount.php
<?php

namespace App\Pricing;

final class Discount
{
    public static function apply(float $price, int $percent): float
    {
        return round($price * (100 - $percent) / 100, 2);
    }
}
PHP main.php
<?php

require __DIR__ . '/vendor/autoload.php';

use App\Pricing\Discount;

echo Discount::apply(80, 25), "\n";
Output
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>:

JSON
{
    "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:

NeedPackages
Datesnesbot/carbon
HTTP clientguzzlehttp/guzzle, symfony/http-client
Templatestwig/twig
Loggingmonolog/monolog
Environment configvlucas/phpdotenv
Emailsymfony/mailer, phpmailer/phpmailer
Testing and qualityphpunit/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.

Try it yourself · main.php
Edit the code, copy it into main.php, then run it with php main.php (PHP 8.5). How to install PHP