Changing a column's type — say, a string that needs to become a text, or an integer that needs to become unsignedBigInteger — uses the same change() method as adding a column, but with a real dependency requirement that trips people up.
The migration
Schema::table('products', function (Blueprint $table) {
$table->text('description')->change();
});
Run it the normal way:
php artisan migrate
The dependency you probably need
On Laravel 10 and earlier, calling ->change() requires doctrine/dbal:
composer require doctrine/dbal
Without it, the migration fails immediately with a clear "class not found" error rather than silently doing nothing — so if you hit this, it's not a sign anything is wrong with the migration itself, just a missing package.
Laravel 11+: doctrine/dbal is no longer required
Laravel 11 replaced the Doctrine-based schema introspection with its own, so a fresh Laravel 11 or 12 project does not need doctrine/dbal for ->change() to work. If you're upgrading an older project that already has it installed, it's safe to remove once you've confirmed nothing else in the app depends on it directly.
Changing a column safely on a table with real data
Two things matter more than the syntax:
- Data compatibility — narrowing a type (e.g.
textdown tostring(255)) can silently truncate existing rows. Check the actual data range before narrowing anything. - A working
down()— write the reverse change explicitly rather than leaving it empty, so a bad deploy can actually be rolled back:
public function down(): void
{
Schema::table('products', function (Blueprint $table) {
$table->string('description', 255)->change();
});
}
On a large production table, also consider whether the change requires a full table rewrite at the database level (most type changes on MySQL/InnoDB do) and plan the deploy window accordingly — this is a database-engine concern, not something the migration file itself controls.