Why this matters
Laravel releases a new major version every year, and each version gets bug fixes for 18 months and security fixes for two years. Applications need to move forward to keep receiving fixes. A Laravel application can only upgrade when every package it depends on can be installed alongside the new framework version.
A package that caps its illuminate/* or laravel/framework constraint at the previous major becomes the thing that blocks the upgrade. Often the code already works; only the constraint is behind.
What good looks like
- The package's
composer.jsonallows the current major version of Laravel. - The test suite runs against the current Laravel version in CI.
- New Laravel majors are supported soon after release, ideally by testing against the release candidates.
How to do it
Widen the constraint
Laravel packages usually depend on specific illuminate/* components rather than the whole framework. Add the new major to each constraint:
{
"require": {
"php": "^8.2",
"illuminate/support": "^11.0 || ^12.0 || ^13.0",
"illuminate/database": "^11.0 || ^12.0 || ^13.0"
},
"require-dev": {
"orchestra/testbench": "^9.0 || ^10.0 || ^11.0"
}
}
Keep the same set of majors across every illuminate/* component. A single component left on an older constraint blocks the whole install.
Check your dependencies
Your package can only be installed with the new Laravel if everything it depends on can too. Run a real resolution in a fresh application:
composer create-project laravel/laravel probe
cd probe
composer require your-vendor/your-package
If Composer refuses, the error message names the dependency that conflicts. Update that dependency, or wait for it to add support, then release.
Test against the new version
Orchestra Testbench gives package tests a Laravel application to run inside. Add the new Laravel version to your CI matrix and run the suite:
strategy:
matrix:
include:
- laravel: '11.*'
testbench: '9.*'
- laravel: '12.*'
testbench: '10.*'
- laravel: '13.*'
testbench: '11.*'
Release
Tag a new version. The constraint on your default branch reaches nobody until it is released.
Things to watch for
replaceandconflictrules. Aconflictentry against a newer framework version, or a dependency thatreplaces an Illuminate component, blocks installation even when the constraints look fine. The resolution test above catches these.- Constraints hidden in dependencies. Your own
composer.jsonmay allow the new version while a package you depend on does not. The install error will name it. - Testing only the newest version. Users on the previous major still need to install your package. Keep the older majors in the matrix until you drop them deliberately, in a new major release of your own.
- Waiting for the stable release. Laravel publishes release candidates ahead of each major. Testing against them gives you a head start.