Skip to main content

On This Page

Migrun: A Minimalist, Dependency-Injection First PHP Migration Runner

2 min read
Share

These articles are AI-generated summaries. Please check the original sources for full details.

Why I Built Migrun

Andrej Rypo developed Migrun to eliminate the technical debt associated with legacy PHP migration tools like Phinx and Phpmig. The system provides an interface-driven approach that allows for autowiring dependencies directly from PSR-11 containers.

Why This Matters

Standalone PHP migration tools often force developers into outdated PHP 5 patterns and rigid inheritance structures that conflict with modern dependency injection practices. In technical reality, database-agnostic builders add unnecessary abstraction layers for features most projects never utilize, while tight coupling to CLI frameworks prevents flexible integration into diverse application architectures.

Key Insights

  • Service container integration in tools like Phinx often requires global static access hacks rather than standard dependency injection (Rypo, 2026).
  • Migrun eliminates rigid class hierarchies by using interfaces and composition instead of requiring the extension of an AbstractMigration class.
  • Query builders introduce unnecessary overhead as most projects never switch databases; Migrun prioritizes raw SQL for simplicity and database-specific features.
  • Decoupling the runner from CLI frameworks like Symfony Console allows Migrun to be integrated into any environment, including web-based migration lists.
  • Modern PHP features like readonly classes and union types are leveraged to create a minimalist tool with zero external runtime dependencies.

Working Examples

Anonymous class migration with autowiring from a service container.

return new class implements Migration { public function up(?PDO $db = null, ?LoggerInterface $logger = null): void { $db->exec("CREATE TABLE users (id INT AUTO_INCREMENT PRIMARY KEY, email VARCHAR(255) NOT NULL UNIQUE)"); $logger->debug("Users table created."); } };

Initializing the Migrun runner using the builder pattern with a PSR-11 container.

$migrun = new MigrunBuilder()->directory(__DIR__ . "/migrations")->container($container)->pdoStorage($container->get(PDO::class))->build(); $migrun->run();

Practical Applications

  • Use Case: PHP projects outside Laravel or Symfony ecosystems use Migrun for lightweight database versioning with native service container support.
  • Pitfall: Extending heavy base classes in legacy tools creates rigid architectures that are difficult to integrate with custom application logic.
  • Use Case: High-performance microservices implement the Migrun Storage interface to track migration history in Redis or alternative backends.
  • Pitfall: Relying on database-agnostic builders often forces developers to write raw SQL anyway for complex schemas, negating the builder primary benefit.

References:

Continue reading

Next article

Fixing 6 Common OpenClaw Failures and Reducing Maintenance Overhead

Related Content