Skip to main content

Documentation Index

Fetch the complete documentation index at: https://kawax.biz/llms.txt

Use this file to discover all available pages before exploring further.

What are migrations?

Migrations are like version control for your database. They let your team define and share the application’s database schema definition. If you have ever had to tell a teammate to manually add a column to their local database after pulling your changes, migrations solve exactly that problem. Migration files are stored in the database/migrations directory. Each filename contains a timestamp that Laravel uses to determine the order in which to run the migrations.

Creating a migration

Use the make:migration Artisan command to generate a new migration file:
php artisan make:migration create_posts_table
Laravel infers the table name from the migration name and generates an appropriate stub. A name like create_posts_table produces a stub that creates the posts table.

Migration structure

A migration class contains two methods: up and down.
  • up — adds tables, columns, or indexes to the database.
  • down — reverses the operations performed by up. Called when rolling back.
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('body');
            $table->boolean('published')->default(false);
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('posts');
    }
};

Available column types

The Blueprint class provides many column type methods:
MethodDescription
$table->id()Auto-incrementing primary key (alias for bigIncrements('id'))
$table->string('name')VARCHAR column (255 characters by default)
$table->text('body')TEXT column
$table->integer('count')INTEGER column
$table->boolean('active')TINYINT used to store a boolean value
$table->timestamp('published_at')TIMESTAMP column
$table->timestamps()Adds created_at and updated_at columns
$table->softDeletes()Adds a deleted_at column for soft deletes
$table->foreignId('user_id')BIGINT UNSIGNED column for a foreign key

Column modifiers

Chain modifier methods to customize column definitions:
$table->string('email')->unique();
$table->string('name')->nullable();
$table->integer('votes')->default(0);
$table->string('title')->after('id'); // Place after a specific column

Running migrations

Run all pending migrations with the migrate command:
php artisan migrate
To check which migrations have run and which are pending:
php artisan migrate:status
Running migrations in production will prompt you to confirm. Use the --force flag to skip the prompt, but be careful — some operations are destructive.

Rolling back migrations

Roll back the most recent batch of migrations with migrate:rollback:
php artisan migrate:rollback
Roll back a specific number of migrations with the --step option:
# Roll back the last 5 migrations
php artisan migrate:rollback --step=5
To roll back all migrations and re-run them:
php artisan migrate:refresh
migrate:refresh drops and recreates all tables, so any existing data is lost. It is useful for resetting your database during development.

Practical example: creating a posts table

Here is the complete workflow for creating a posts table for a blog application.

1. Generate the migration file

php artisan make:migration create_posts_table

2. Edit the migration

Open database/migrations/xxxx_xx_xx_xxxxxx_create_posts_table.php and define the schema:
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id')->constrained()->cascadeOnDelete();
            $table->string('title');
            $table->text('body');
            $table->boolean('published')->default(false);
            $table->timestamp('published_at')->nullable();
            $table->timestamps();
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('posts');
    }
};

3. Run the migration

php artisan migrate
After running the command, the posts table is created in your database.

4. Adding a column later

When you need to add a column after a table has already been created, create a new migration instead of modifying the existing one:
php artisan make:migration add_excerpt_to_posts_table
public function up(): void
{
    Schema::table('posts', function (Blueprint $table) {
        $table->string('excerpt')->nullable()->after('title');
    });
}

public function down(): void
{
    Schema::table('posts', function (Blueprint $table) {
        $table->dropColumn('excerpt');
    });
}
Never modify an existing migration file that has already been run. Doing so breaks consistency with your teammates and with production. Always add changes as a new migration.

Next steps

Database seeding

Learn how to populate the tables you created with sample data using seeders.

Eloquent ORM

Learn how to interact with the tables you created using Eloquent.
Last modified on April 3, 2026