Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Migrations Laravel Package

cycle/migrations

Cycle Database Migrations provides structured, versioned database schema changes for PHP applications. Configure a migrations directory and vendor paths, initialize the migration table, then run migrations programmatically or generate migration files during schema compilation.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit — first, a correction to the record. The prior assessments in this bundle (assessment-pm.md, assessment-tpm.md) describe cycle/migrations as a Laravel/Eloquent package that integrates with Illuminate\Support\Facades\Schema, php artisan make:migration, and Laravel's Migrations facade. This is factually wrong and should be corrected before it reaches a decision log. cycle/migrations is the migration component of the Cycle ORM / Spiral Framework ecosystem (namespace Cycle\Migrations, formerly Spiral\Migrations). It has no service provider, no Artisan commands, no Eloquent awareness, and no Laravel integration of any kind. It operates on Cycle\Database (DatabaseManager, driver configs, TableBlueprint) and is driven programmatically:

$migrator = new Migrations\Migrator($config, $dbal, new Migrations\FileRepository($config));
$migrator->configure();
while (($migration = $migrator->run()) !== null) { /* ... */ }

Any roadmap commitment built on the premise "generate migrations from Eloquent models with one command" is built on a package that cannot do that.

What the package actually is. A small, focused schema-versioning library: a Migrator orchestrator, a FileRepository for on-disk migration files, a MigrationConfig (migration directory, vendorDirectories, tracking table, safe flag), and a TableBlueprint DSL for writing up()/down() in PHP. Its headline capability — automatic migration generation from a compiled schema — lives in a separate package, cycle/schema-migrations-generator. That is a material procurement detail: adopting "automatic migration generation" means vetting two repositories, two release cadences, and two maintenance trails, not one.

Integration feasibility. Feasible and straightforward if and only if the surrounding stack already uses Cycle\Database as its DBAL. In that case the API surface is tiny and the mental model is conventional (ordered files, a ledger table, up/down). The vendorDirectories option is a genuinely useful primitive for modular monoliths and internal package distribution, and the safe flag supports non-interactive CI execution. Outside that context, adoption means pulling in a parallel database abstraction layer purely to run DDL — technically possible, organizationally expensive.

Technical risk. Code-level risk is low: MIT license, small dependency footprint, active patch releases (v4.2.4–v4.2.6 show read-only-schema handling, Psalm/CS hardening, PHP 8.4 deprecation fixes, and a foreign-key ordering fix). The real risks are stack-mismatch risk and bus-factor risk. 21 stars and zero declared dependents means the community is effectively the Spiral user base; maintenance is single-vendor (Spiral Scout). Version 4.0 was a breaking release driven by an upstream framework change (Spiral 3.0 / new Reactor), which tells you the release cadence is coupled to that framework's evolution rather than to a stable public contract.

Key questions to resolve before any commitment:

  • Are we standardizing on Laravel/Illuminate, or is this service on Spiral/Cycle or framework-agnostic PHP? (If the former: this is the wrong tool, full stop.)
  • Do we need the generator (cycle/schema-migrations-generator) or only the runner? The scope and risk profile differ substantially between "one library" and "two."
  • Which database engines are in scope, and what does Cycle\Database's driver support look like for each? Verify against our actual prod engine, not SQLite in-memory.
  • Is there any scenario where this would run against the same schema as an existing Laravel migration ledger? (There must not be — two runners, two tracking tables, two sources of truth.)
  • Who owns the migration ledger in CI/CD, and what is our locking story for concurrent deploys?
  • What is the exit path if the vendor deprioritizes the package? MIT means forkable, but forking a migration tool is a multi-quarter tax.

Integration Approach

Stack fit — the honest verdict. For a Laravel-standardized organization, the correct integration approach is not to integrate this package. Illuminate\Database\Migrations already provides migration generation, a version ledger, rollback, batching, and — critically — an installed base of engineers and documented patterns. Layering cycle/migrations alongside it produces two competing schema authorities and no commensurate gain. Adoption is defensible in three narrower situations: (1) a service already running Spiral/Cycle ORM that needs vendor-package migrations; (2) a framework-agnostic internal PHP library that must ship schema changes with itself; (3) a context where migrations must be invoked from application/runtime code rather than a CLI — the while ($migrator->run()) loop is well-suited to long-running workers (RoadRunner, Swoole) and bootstrap scripts, which is a genuine differentiator versus Artisan-centric tooling.

Migration path. Two distinct paths, and they should not be conflated:

  • From spiral/migrations: the v3.0 rename to Cycle\Migrations is a namespace-and-config swap; v4.0's Atomizer/Reactor rework is the breaking boundary. Plan a dedicated upgrade ticket with a full generate→run→rollback rehearsal.
  • From Laravel into this package: treat as a greenfield-per-database move, not a migration of migration history. Pick one bounded context or one physically separate database, start the cycle/migrations ledger at a baseline snapshot, and leave the existing Laravel ledger untouched on its own schemas. Never point both runners at one schema.

Compatibility checks to run in a spike (timebox: 2–3 days).

  • PHP floor is 8.1+ for the 4.x line; confirm against the runtime matrix, including any PHP 8.4 targets (4.2.5 exists specifically to fix implicit-nullable deprecations — good signal, but verify our exact minor).
  • Composer resolution: cycle/database version constraints against existing doctrine/dbal/PDO-adjacent packages. Expect resolvable, but pin explicitly in composer.json rather than floating ^4.0.
  • Driver parity: confirm generated DDL is correct for our production engine, not just SQLite. Binary sizes, column attributes (first/after, CURRENT_TIMESTAMP), and foreign-key index behavior have all been patched recently, which suggests non-uniform maturity across engines.

Sequencing.

  1. Correct the decision record; re-baseline expectations to "Cycle/Spiral migration runner, generator is a separate dependency."
  2. Spike: pin versions, run the full round trip (configure → generate → review → run → rollback → re-run) on a throwaway database matching production engine.
  3. Wrap the Migrator in a thin internal adapter/CLI (bin/db-migrate) so application code and CI depend on our interface, not on Cycle\Migrations directly. This is the single highest-leverage step for reversibility.
  4. Add an external advisory lock around the runner if we have multi-replica deploys; the package does not provide a distributed lock.
  5. Wire into CI/CD only after the wrapper exists; enforce safe: false everywhere except the automated pipeline, where confirmation is surfaced as a pipeline approval gate instead.
  6. Only then evaluate cycle/schema-migrations-generator as a separate adoption decision.

Operational Impact

Maintenance. Low ongoing effort, non-trivial ownership cost. The package changes slowly and mostly in response to PHP releases and upstream framework shifts. MIT licensing means we can fork, but a fork of a migration tool becomes internal infrastructure with no upstream to lean on — budget that as a contingency, not a plan. Track releases monthly rather than pinning blindly; the 4.2.x line has shipped meaningful correctness fixes (foreign-key ordering, binary sizing, array_multisort argument ordering, read-only schema skipping) that we would want.

Support. No commercial support tier for the package itself; support flows through the Spiral Scout community channels and the source code. Documentation is README-level — installation, configuration, a run loop, and a pointer to the generator. Engineers will read Migrator, FileRepository, and TableBlueprint to answer non-trivial questions. Factor this into onboarding estimates explicitly rather than assuming "it's just migrations."

Scaling. Runtime cost is per-migration DDL, so scaling is a function of schema-change volume, not traffic — not a concern. The scaling concern is concurrency: multiple app replicas or parallel CI jobs racing the same ledger. Implement a lock (advisory lock, or a lease row in the tracking table) at the wrapper layer. vendorDirectories scales fine for a handful of packages; ordering and precedence across many vendor directories is where it gets fragile, so keep the list short and explicit.

Failure modes to instrument for.

  • Non-transactional DDL on MySQL — a failed mid-migration statement leaves a partial schema with the ledger unaware. Requires manual repair runbook; test this deliberately.
  • safe: true leaking into a production path — this flag suppresses the confirmation prompt. Gate it at the CLI wrapper, not in the shared config object.
  • Read-only schema skip (added 4.2.4) — correct behavior, but it can silently mask an intended-to-fail migration on a replica. Log the skip loudly.
  • Vendor-directory ordering collisions — two packages introducing conflicting changes; detect in CI by diffing the compiled schema before and after.
  • Schema drift between the Cycle schema definition and hand-edited migrations — generation is a compile-time snapshot; hand edits diverge silently. Require a schema-diff check in CI if the generator is adopted.
  • Dual-ledger divergence — the highest-severity failure mode in any hybrid Laravel scenario. Alert on unexpected row counts in the migrations table.

Ramp-up. For a PHP engineer who has used any migration tool: approximately 1–2 days to first productive migration, with the learning curve concentrated in the TableBlueprint DSL and the migrator lifecycle. Add 0.5–1 day if cycle/schema-migrations-generator is in scope. Add 1 day for whoever writes the internal wrapper and CI integration. Compare against roughly 2 hours for an engineer already fluent in Laravel migrations — that delta is the clearest single argument against adoption in a Laravel shop.

TPM recommendation. Do not adopt on the basis of the existing assessments; they describe a different package. Re-open the evaluation as a conditional no for Laravel-standardized services and a conditional yes for Cycle/Spiral or framework-agnostic PHP services where runtime-invoked migrations or vendor-package migrations are a real requirement. Require a 2–3 day spike with the adapter-wrapper deliverable before any roadmap commitment, and treat the generator as a separate, later decision.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log