nkmryu/laravel-strong-migrations

Detect potentially dangerous Laravel database migrations before they are deployed.

Maintainers

Package info

github.com/nkmryu/laravel-strong-migrations

pkg:composer/nkmryu/laravel-strong-migrations

Transparency log

Statistics

Installs: 2

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.1.0 2026-08-02 05:13 UTC

This package is auto-updated.

Last update: 2026-08-03 01:34:14 UTC


README

Laravel Strong Migrations detects potentially dangerous database migrations before they are deployed. It brings the safety-oriented workflow of ankane/strong_migrations to Laravel projects using structural PHP AST analysis.

Requirements

  • PHP 8.3 or later
  • Laravel 12 or later

Install

Install the package with Composer:

composer require --dev nkmryu/laravel-strong-migrations

Publish the optional configuration file:

php artisan vendor:publish --tag=strong-migrations-config

Usage

Lint the configured migration paths:

php artisan migration:lint

Use CI mode to fail when a finding meets the configured fail_on severity:

php artisan migration:lint --ci

Use JSON output or override the paths when integrating with other tools:

php artisan migration:lint --json --path=database/migrations --path=packages/example/database/migrations

Add #[SafetyAssured(reason: '...')] to a migration's anonymous class only after reviewing and accepting the operation's safety.

Rules

Rule Severity What it detects
DropColumnRule High Columns dropped while deployed application instances may still use them.
DropTableRule High Tables dropped while deployed application instances may still query them.
RenameColumnRule High Column renames that are incompatible with old application instances.
RenameTableRule High Table renames that are incompatible with old application instances.
ChangeColumnRule High Column changes that may lock or rebuild a table.
AddNotNullColumnRule High Required columns added without a default for existing rows.
RawDdlRule High Raw DDL that bypasses structural safety checks.
AddIndexRule Medium Index creation that may scan a table and block writes.
AddUniqueIndexRule Medium Unique index creation that may block writes or fail on duplicate data.

Configuration

The published config/strong-migrations.php file supports these keys:

Key Description
migration_paths Files and directories scanned by migration:lint. The default is database/migrations.
contract_paths Migration paths excluded from linting because they contain deliberate contract operations. In an expand/contract workflow, place migrations that remove old columns or tables here and run them only after all deployed code has stopped using the old schema. The default is database/migrations/post-deploy.
start_after An optional migration timestamp in YYYY_MM_DD_HHMMSS format. Migrations at or before this value are ignored, which lets an existing project adopt the package without reporting its full migration history. Newer migrations remain checked.
disabled_rules Rule class names to skip, such as AddIndexRule. Keep this list empty unless the project has a documented alternative safety control.
fail_on The minimum severity that makes migration:lint --ci fail. Use high to fail only on high-severity findings or medium to fail on both medium- and high-severity findings.

Safety assurance

Use SafetyAssured only when a specific migration has been reviewed and the reason can be recorded in code. Apply the attribute to the anonymous migration class:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Nkmryu\StrongMigrations\SafetyAssured;

return new #[SafetyAssured(reason: 'The application stopped reading this column in the previous release.')] class extends Migration
{
    public function up(): void
    {
        Schema::table('users', function (Blueprint $table): void {
            $table->dropColumn('legacy_name');
        });
    }
};

Why

Zero-downtime schema changes usually follow the expand/contract pattern: add the new schema first, migrate application behavior and data, then remove the old schema later. During a deployment, old application instances may still run while migrations and new instances start, so an immediate rename or removal can break live requests. Laravel Strong Migrations catches operations that violate this overlap and points toward staged alternatives. This package is inspired by and pays respect to ankane/strong_migrations, which established this safety-oriented workflow for Rails applications.