Managing Contao Extensions with Composer: A Practical Guide
Learn how Composer powers Contao extensions—install, version‑control, and verify custom modules reliably across environments. A step‑by‑step guide with real commands, trade‑offs, and practical checks.
30 May 2026, 03:04 UTC

Why Composer Matters for Contao Extensions
When you drop a custom module into a Contao site, you want to be sure that it behaves the same on your dev box, your staging server, and production. The traditional way of copying files into extensions/ or vendor/ quickly leads to “works on my machine” headaches. Composer turns that pain into a predictable workflow: each extension declares its own dependencies, autoload rules, and version constraints in a composer.json file, and the Contao core consumes it just like any other PHP package.
1. Composer as the Extension Manager
Contao 5 ships with a fully integrated Composer setup. When you run composer require, Composer pulls the extension into vendor/contao/extension‑example, updates vendor/autoload.php, and records the exact version in composer.lock. The Contao backend then scans vendor/ for any contao‑extension packages and automatically registers new modules, widgets, or templates.
2. Installing a Custom Module via Composer
Suppose you write a small “Hello World” module and package it under contao/hello-world. Your composer.json inside the extension might look like this:
{
"name": "contao/hello-world",
"type": "contao-extension",
"require": {
"contao/core-bundle": "^5.0"
},
"autoload": {
"psr-4": {"Contao\\HelloWorld\\": "src/"}
},
"extra": {
"contao": {
"extension": "hello-world"
}
}
}
From the root of your Contao project, run:
composer require contao/hello-world
Composer will resolve the contao/core-bundle dependency (ensuring it matches your site's core version), download the package, and update vendor/autoload.php. No manual file moves are necessary.
3. Post‑Install Hooks & Database Migrations
Many extensions need to create or alter database tables. You can let Composer run those hooks automatically by adding a scripts section to the extension’s composer.json:
"scripts": {
"post-install-cmd": ["Contao\\HelloWorld\\Installer::run"]
}
During composer install or composer update, Composer will invoke Contao\HelloWorld\Installer::run(), which can call php vendor/bin/contao-migrate or any custom migration logic. This keeps the module self‑contained.
4. Verifying the Installation
- Composer list: In the project root, run
composer show | grep hello-world. You should see the exact version number recorded. - Backend check: Log into Contao’s backend, navigate to Extensions → Modules, and confirm that the new module appears and can be activated.
- Composer.lock: Open
composer.lockand verify that thecontao/hello-worldentry matches the version from step 1. - Database migration: If the module includes migrations, run
php vendor/bin/contao-migrateand look for a success message. Optionally, inspect the database to confirm the new table exists.
These checks give you confidence that the extension is correctly installed, version‑controlled, and ready for deployment.
5. Trade‑offs & Limitations
- PHP version: Composer requires PHP 7.4+. Running it on older PHP will fail.
- Version conflicts: If an extension demands a Contao core range that clashes with your project, Composer will refuse installation. You may need to adjust the core or wait for an updated extension.
- Legacy extensions: Some older Contao addons are not Composer‑ready. They still need manual copying or a custom patch in
composer.json. - Vendor bloat: Large extensions inflate
vendor/. Use Contao’s optional module system or split the extension into smaller packages if you need to keep the codebase lean.
6. Actionable Takeaway
Adopt Composer for every Contao extension you add. It gives you:
- Deterministic dependencies and version pinning via
composer.lock - Automatic autoloading and backend discovery
- Built‑in hooks for database migrations
- Seamless integration with CI/CD pipelines
Next step: package your own module as a Composer package, run composer require, and follow the verification steps above. Your deployment pipeline will be cleaner, and your team will spend less time chasing environment differences.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.