webparking/laravel-db-rebuild
A Laravel package that adds a db:rebuild Artisan command to quickly reset your database by dropping all tables, rerunning migrations, and optionally seeding. Ideal for local development and testing, it makes repeatable database refreshes fast, consistent, and simple without manual SQL.
Assessment status: adopt-with-conditions, defaulting to build-not-buy. This package is a single Artisan command that drops all tables, re-runs migrations, and optionally seeds. It belongs in the development/CI tooling bucket, not the runtime dependency bucket — a materially smaller blast radius than a request-path library, but with one sharp edge: the command is destructive by design, so the dominant risk is misfire, not coupling.
Architecture fit. The integration surface is about as small as Laravel packages get: one console command, registered via a service provider (auto-discovered through extra.laravel.providers) or an explicit $commands array. No facades, no middleware, no queue jobs, no schema mutations we inherit. Fit against a conventional Laravel 11/12 app is high in shape and questionable in value, because Laravel core already ships migrate:fresh, migrate:refresh, migrate:reset, db:wipe, and --seed / --seeder. On paper, php artisan db:rebuild ≈ php artisan migrate:fresh --seed. The TPM question is therefore not "how do we integrate this" but "what does this give us that the framework does not, and is that delta worth a dependency we must maintain?" If the answer is "nothing but a shorter command name," the correct decision is a two-line internal wrapper, not a third-party package.
Integration feasibility. Mechanically trivial: composer require --dev webparking/laravel-db-rebuild, confirm discovery, run the command against a disposable database. Elapsed effort for the spike is hours. The feasibility risk is entirely in compatibility, because the last release is 2020-09-10 — pre-dating Laravel 9, 10, 11, and 12, and predating PHP 8.1+. Two concrete unknowns:
Artisan::starting() or assumes app/Console/Kernel.php may register cleanly but behave unexpectedly, or not at all.illuminate/support and illuminate/console ranges that stop at Laravel 7/8. Adding it to a Laravel 11/12 lockfile will either fail the solve or require a constraint override / fork — at which point we are maintaining a fork of a dev tool, which is a poor trade.Because it is dev-only, this risk is containable (require-dev, excluded from production images via composer install --no-dev), but it is not free: CI images install dev dependencies, so a constraint conflict still blocks the pipeline.
Technical risk. Ranked by expected impact:
DB_HOST/DB_DATABASE env var in CI, or a developer running it with a production/staging .env loaded, is a data-loss incident. This is the single reason to gate adoption on guardrails rather than convenience.migrate:fresh --seed, we take on upgrade coupling and a fork obligation for zero capability gain.composer.lock and block a Laravel major.Key questions. Answer before converting from provisional to a decision:
db:rebuild do that migrate:fresh --seed does not? Enumerate the actual diff in behaviour, flags, and edge cases.require constraints does the tagged release declare, and does it solve against our current composer.lock on Laravel 11/12 and PHP 8.2–8.4 without overrides?--force flag, or an environment guard (APP_ENV !== production) before dropping tables?--dry-run or any non-destructive mode?Stack fit. Treat this as CI/dev-only tooling: require-dev in composer.json, absent from production images, never referenced by application code. It should sit alongside PHPUnit, Pint, and Larastan in the "tooling we could rewrite in an afternoon" category. If any proposed use case touches a shared, persistent, or staging database, stop — that is out of scope for this class of tool.
Migration path. Sequence the cheap disproof first, because the most likely outcome is "we don't need this":
migrate:fresh --seed and db:rebuild against the same throwaway database and diff the resulting schema (table counts, views, indexes, FK constraints). If the schemas match, the package is redundant and the evaluation ends here.APP_ENV/DB_HOST allowlist check in our CI wrapper, DB name convention for ephemeral databases, and a confirmation prompt retained for interactive use.migrate:fresh step, then roll to others.If the redundancy check fails (the package genuinely adds capability), the fallback is a ~20-line internal Artisan command wrapping db:wipe + migrate --seed, which removes the dependency entirely at roughly the same engineering cost as the guardrail work above.
Compatibility. Three axes to clear:
--seed use our DatabaseSeeder, and does it fail loudly or leave a half-seeded database?Sequencing. Do not introduce this and a Laravel major upgrade in the same change. Land the guardrails (step 3) with or before the first shared-pipeline use — a destructive command without an environment guard should never reach CI. If replacing an existing make-target or script, run both in parallel for one iteration and compare resulting schemas before deleting the incumbent.
Maintenance. Low absolute cost, but asymmetric: the package has had no release in ~5 years, so any framework incompatibility is ours to fix, not upstream's. Budget 1–2 hours per Laravel major to verify the command still works, plus the possibility of a one-time fork if it doesn't. The dependency's real cost is that it sits in the lockfile and can block a framework upgrade for a convenience command — a poor leverage ratio. Mitigation: keep it dev-only and pre-accept that we will replace it with an internal command at the first sign of friction.
Support. Community-only, effectively unmaintained. Acceptable here only because it never runs in production and its failure mode is "CI step errors," not "customer-facing incident." Confirm we can read and patch the source (MIT permits it) — a 2020-vintage package that breaks on the next major should be forked or replaced, not worked around.
Scaling. Runtime scaling is not applicable; the relevant "scale" is CI throughput and database provisioning:
schema:dump) or per-worker ephemeral databases rather than optimising the rebuild command.Failure modes.
| Failure mode | Signal | Control |
|---|---|---|
| Command run against staging/production | Tables dropped, data loss | Environment guard + host allowlist in wrapper; never expose in prod image (--no-dev) |
| Constraint conflict blocks framework upgrade | Composer solver error | Spike before commitment; dev-only placement limits but does not remove the risk |
| Package unmaintained, breaks on Laravel major | Command missing or errors post-upgrade | Pin exact version; fork readiness; fallback internal wrapper |
| Silent incompleteness (views/triggers/sequences survive) | Schema drift between rebuilds | Diff schemas vs migrate:fresh in the spike; fail CI on drift |
| Concurrent CI jobs collide | Intermittent "table already exists" / missing table | Per-job unique database name; no shared CI database |
| Seeder failure mid-run | Partially populated DB, flaky tests | Fail-fast seeding; treat non-zero exit as pipeline failure, no retry |
| Timeout on larger schemas | CI step exceeds budget | Measure; consider schema dump baseline |
Ramp-up. Near-zero. Any Laravel engineer understands artisan db:rebuild from the name alone. The non-obvious knowledge worth capturing in a one-paragraph runbook is the safety envelope: which environments it may target, how ephemeral databases are named, and what to do when it fails. That runbook is the actual deliverable of the integration, more so than the dependency itself.
Conditional recommendation. Default to build, not adopt: an internal command wrapping db:wipe + migrate --seed delivers the same outcome with no dependency, no 2020 constraint risk, and full control over destructive-safety guards. Proceed to adopt the package only if (a) the redundancy check shows a genuine capability gap we would otherwise have to implement, and (b) it resolves cleanly against our current Laravel 12 / PHP 8.2–8.4 lockfile without overrides. If either gate fails, close as "no action — covered by framework core."
How can I help you explore Laravel packages today?