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

Factory Generator Laravel Package

laravel-shift/factory-generator

Generate Laravel model factories automatically from your existing database schema. This Laravel Shift package inspects table columns and writes realistic Faker-based definitions, saving hours when adding tests or seed data to legacy applications.

View on GitHub
Deep Wiki
Context7

Getting Started

laravel-shift/factory-generator is a dev-only codegen tool: it introspects your database schema and writes database/factories/*Factory.php files with Faker calls mapped to each column's type. Its value is highest in legacy/large-schema apps where hand-writing 40 factories is the reason tests never get written.

composer require laravel-shift/factory-generator --dev

Generate everything, or one model at a time:

php artisan generate:factories          # all discovered models
php artisan generate:factories User     # single model

(If the command name differs in your pinned version, php artisan list | grep generate will show it — the entry point is the same.)

Where to look first:

  1. The generated file, not the docs. Open database/factories/UserFactory.php and read every Faker call — that output is the package's opinion about your schema.
  2. vendor/laravel-shift/factory-generator/src/, specifically the column-type→Faker mapping. When a generated value is wrong, the map is almost always why, and it's the thing you'll want to override.

Best first use case: pick one mid-sized model with a messy table (foreign keys, nullable columns, an enum), generate just that factory, and diff it against a hand-written one. That single exercise tells you whether the output is 80% usable or 20% usable for your schema, which determines whether you adopt it wholesale or only for bootstrap.

v2.3 adds Laravel 13.x compatibility. If you're planning a Laravel 13 upgrade, this is the version that lets you keep the tool in the upgrade branch — but see the regeneration note in Gotchas.

Implementation Patterns

Bootstrap-then-own. Treat generated factories as a first draft you commit and then edit, not as artifacts you regenerate continuously. The productive loop is: generate → review each file → extract anything hand-tuned into state methods → commit.

Generate against a representative schema. The generator reads the live database connection, so fidelity depends entirely on what's migrated. Run it against a database built from your real migrations (ideally the same driver as production), not a half-migrated local SQLite file.

Generate in dependency order for foreign keys. Foreign-key columns become Model::factory() references. If the parent factory doesn't exist yet, you get a broken reference. Either run the command twice (second pass picks up newly created parents), or generate parent models first.

Schema-change workflow. After a migration adds/renames columns, regenerate that one model and diff:

php artisan generate:factories Invoice
git diff database/factories/InvoiceFactory.php

Small, per-model diffs are reviewable. A full generate:factories run is not.

Split hand-written behaviour into states, not inline edits. Keep generated attribute arrays pristine-ish and add domain states below them:

public function overdue(): static
{
    return $this->state(fn () => ['due_at' => now()->subWeek(), 'status' => InvoiceStatus::Overdue]);
}

States survive a regeneration diff far more readably than scattered edits inside definition().

Seeder + test integration. Generated factories are immediately usable for local dev seeding (Invoice::factory()->count(50)->create()) and for the first test in each model's suite. The realistic adoption path in a legacy app is: generate all factories, then write tests model by model, fixing each factory as you go — the factory gets correct exactly when a test needs it to be.

Post-process what can't be inferred. Enums, JSON shapes, money/currency pairs, and constrained foreign keys (role_id pointing at a fixed set of rows) have no schema signal. Plan a manual pass over those columns; don't expect the tool to guess them.

Gotchas and Tips

  • Unique columns will bite you on count(). Mapping a string column to $faker->word ignores unique indexes. Any ->count(n) on an email, uuid, or slug column will throw. Add ->unique() (or a sequence) manually — this is the single most common first failure.
  • --force clobbers hand edits. Regeneration overwrites existing factories. Commit before regenerating, and prefer per-model regeneration over bulk once you've started customising.
  • Nullable columns are a coin flip. The generator tends to emit either a value or null for nullable columns, not a mix. If your tests care about both paths, add explicit states.
  • Enum and JSON columns are placeholders. Expect a random string or empty array. Replace with real enum cases / realistic payloads before trusting the factory in assertions.
  • Soft deletes and timestamps. created_at/updated_at are skipped and deleted_at is typically left null. Add a trashed() state if you test soft-delete behaviour, and use ->state(['created_at' => ...]) when you need backdated rows.
  • Pivot tables and model-less tables are invisible. The tool works from models, so tables without one (pivots, log tables, legacy junk) are skipped silently. That's fine — but don't assume "no factory" means "no table."
  • Driver-dependent type detection. MySQL enum, Postgres jsonb, and SQLite's loose typing (no native boolean) produce different mappings. If type fidelity matters, generate against the production driver; otherwise review boolean/date columns extra carefully on SQLite.
  • Model discovery. If a model isn't picked up, run composer dump-autoload first — the scanner relies on autoloading, and non-standard namespaces are a frequent cause of "it generated 12 of my 15 factories."
  • Keep it in require-dev. It's a schema-introspecting dev tool; nothing at runtime needs it, and you don't want its dependencies in a production image.
  • Upgrading: v2.3 is the Laravel 13-compatible release — pin ^2.3 before moving an app to Laravel 13. Note that major Laravel upgrades change the schema-inspection API underneath the generator, so diff generated output after the upgrade rather than assuming identical results; type mappings can shift even when the package version is unchanged.
  • Debugging a wrong value: compare Schema::getColumns('your_table') against the generator's type map. If the column type reported by the schema builder doesn't match what you expect, the bug is in your database, not the package.
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.
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle