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

Laravel Conditional Migrations Laravel Package

mll-lab/laravel-conditional-migrations

Laravel Conditional Migrations adds condition-based execution to your database migrations, letting you run or skip specific migration files when predefined criteria are met. Ideal for environment-specific schema changes, feature rollouts, and safer deployments.

View on GitHub
Deep Wiki
Context7

Getting Started

Check the deprecation first. This package is archived and explicitly deprecated in favor of mll-lab/laravel-utils v4.0.0. New work should start at the successor package — read its migration/condition docs before installing anything here. Only invest in this package if you are inheriting an existing codebase that already depends on it, or you have a hard constraint keeping you on the Laravel versions it supports.

Install (existing codebases only). composer require mll-lab/laravel-conditional-migrations against a Laravel version outside the known-bad 9.21 patch. Confirm composer.json require/conflict constraints before scoping — the v3.1.1 release note ("Mark Laravel 9.21 as unsupported") signals patch-level compatibility handling, so treat the supported matrix as a first-class artifact and pin the exact Laravel patch in composer.lock.

Where to look first.

  1. The package source's service provider and its hook into migrate / migrate:rollback — that is where the condition gate actually lives.
  2. The base migration class or trait the package exposes for declaring conditions.
  3. The successor package's equivalent API, so you know the migration shape you'd move to if you adopt it later.

First use case. Environment- or config-gated schema changes: a migration that creates a PostGIS extension, sets up a staging-only view, or seeds reference data that must not exist in production. Instead of branching in the migration body (or wrapping migrate in a script), you declare the condition on the migration and let the package decide whether it executes during a normal php artisan migrate.

Implementation Patterns

Environment gate. Attach a condition that returns true only when app()->environment() is in an allowlist. Typical targets: extension creation, full-text search setup, or partitioning that only certain environments provision. Keep the allowlist in config rather than hard-coding environment names in each migration.

Config / feature-flag gate. Return the value of a dedicated config key (e.g. config('features.partitioning')). This is the cleanest pattern for optional schema changes that ship in one release but are enabled later per deployment. It also makes the gate testable — flip the config in tests instead of faking the environment.

Capability probes as conditions. Conditions can be arbitrary logic, so probe the database rather than the environment when the real question is "does this driver support X?" — check the connection driver, server version, or Schema::hasTable. Be careful to keep these cheap and side-effect free; they execute on every migrate.

Paired migrations. When a schema change is conditional, write its rollback with the same condition so migrate:rollback stays symmetric. The package claims consistent behavior across migrate and migrate:rollback — verify that symmetry for each conditional migration you add, because an asymmetry here is exactly what leaves environments in divergent states.

Testing workflow. Make conditions deterministic in the test suite: set the environment and any config flags explicitly in phpunit.xml / TestCase::setUp rather than relying on defaults. Run migrate:fresh in CI to prove the conditional set produces a valid schema from scratch, not just incrementally.

Rollout sequencing. Land the migration and its condition together, and document in the PR why the condition exists. A condition with no rationale is indistinguishable from dead code six months later, and nobody will dare flip it.

Gotchas and Tips

Deprecation is the headline gotcha. No fixes, no security patches, no new Laravel major support, and effectively no community (1 star, 0 dependents). Any bug you hit is yours to patch in a fork. Budget the successor migration as part of adoption, not as a later cleanup.

Patch-level Laravel pinning. The 9.21 exclusion means minor-version compatibility claims are insufficient. Capture the exact Laravel patch per service and add a CI gate that fails on drift into unsupported patches. Determine whether 9.21 is excluded via a conflict entry (composer refuses to install) or documentation only (composer silently installs into an untested combination) — the two failure modes are very different.

Skipped ≠ forgotten — verify migration history semantics. "Keeps migration history consistent" most plausibly means a skipped migration is still recorded as run so it is not retried on every deploy. If that's the case, flipping a condition from false to true later will not re-run the migration — you need a new migration to apply the change. Confirm this against the source before you rely on a condition as a toggle; the opposite assumption is a classic way to end up with a schema that differs from what the migration file says.

Condition evaluation is invisible by default. A migration that silently does nothing looks identical to one that ran and changed nothing. Log condition decisions (or check the migrations table rows and timestamps) when debugging; don't assume --pretend will faithfully evaluate conditions, since the gate may run outside the pretend path.

Keep conditions pure. No writes, no expensive queries, no calls to services that may be down during a deploy window. A condition that throws will fail the whole migrate run, which is a worse outcome than the migration simply not applying.

Rollback asymmetry. If a conditional migration ran on one environment and its condition is now false, rollback will skip it and leave the schema change in place. Treat conditions as write-once per environment: once a conditional migration has run somewhere, changing its condition retroactively is a footgun.

Extension point. If the package allows custom condition classes, that's the cleanest place to centralize repeated logic (driver checks, feature flags) — but any extension you build is now coupled to an archived package, so keep it thin and easy to port to the successor API.

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.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core