jeremykenedy / laravel-seedster
Register and run Laravel database seeds from packages. Fork of eklundkristoffer/seedster with Laravel 13+ support.
Requires
- php: ^8.2
- illuminate/console: ^9.0|^10.0|^11.0|^12.0|^13.0
- illuminate/database: ^9.0|^10.0|^11.0|^12.0|^13.0
- illuminate/support: ^9.0|^10.0|^11.0|^12.0|^13.0
Requires (Dev)
- laravel/pint: ^1.18
- orchestra/testbench: ^7.0|^8.0|^9.0|^10.0|^11.0
- pestphp/pest: ^2.0|^3.0|^4.0
- pestphp/pest-plugin-laravel: ^2.0|^3.0|^4.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-11 14:42:47 UTC
README
Let a Laravel package register its own database seeders and have them run
as part of the normal db:seed command, with no changes to the host application.
Table of Contents
- Requirements
- Installation
- Quick Start
- How It Works
- Artisan Commands
- Console Output
- Translations
- Laravel Support
- Upgrading
- Testing
- Credits
- License
Requirements
- PHP 8.2 or newer
- Laravel 9 through 13
Installation
composer require jeremykenedy/laravel-seedster
The service provider is auto discovered. There is nothing to register and no configuration file to publish.
Quick Start
Register your seeders from any service provider:
use Illuminate\Support\ServiceProvider; use Mypackage\Database\Seeders\PostsTableSeeder; use Mypackage\Database\Seeders\UsersTableSeeder; class MypackageServiceProvider extends ServiceProvider { public function register(): void { $this->app['seed.handler']->register(UsersTableSeeder::class); // Or register several at once. $this->app['seed.handler']->register([ UsersTableSeeder::class, PostsTableSeeder::class, ]); } }
That is the whole API. The host application keeps running php artisan db:seed exactly as before, and your seeders run with it.
If your package should work with or without Seedster installed, hook the binding instead of requiring it:
$this->app->afterResolving('seed.handler', function ($handler): void { $handler->register(UsersTableSeeder::class); });
The callback never fires when Seedster is absent, so the package stays installable on its own.
How It Works
Seedster binds a seed.handler singleton that holds a collection of seeder class names, and replaces the framework db:seed command with a subclass of it.
When db:seed runs, the replacement resolves the root seeder the way Laravel always has, then wraps it so the registered seeders run first:
- Every registered seeder runs, in the order it was registered.
- The root seeder runs last. That is the
classargument, the--classoption, orDatabase\Seeders\DatabaseSeederby default.
Because the command is a subclass of Illuminate\Database\Console\Seeds\SeedCommand, everything the framework command does still applies: the production confirmation, the --force bypass, unguarded models during seeding, and restoring the previous default connection after seeding a different one.
One framework caveat carries through with it. Only Laravel 13 restores that connection when a seeder throws; on Laravel 9 through 12 the restore sits after the call rather than in a finally, so a failed seed leaves --database in effect for the rest of the process. That is how db:seed behaves on those versions with or without this package.
When no package has registered anything, db:seed behaves exactly like the framework command.
Artisan Commands
Seedster adds no commands of its own. It extends the one Laravel already ships.
| Command | Description |
|---|---|
db:seed |
Seed the database with records. Runs registered package seeders, then the root seeder. |
| Argument or option | Description |
|---|---|
class |
The class name of the root seeder. |
--class |
The class name of the root seeder. Defaults to Database\Seeders\DatabaseSeeder. |
--database |
The database connection to seed. |
--force |
Force the operation to run when in production. |
A seeder registered by its short name resolves out of the application seeder namespace, matching how db:seed treats a bare class value.
Console Output
Registered seeders report through the standard Laravel seeder output, with a line naming how many came from packages:
INFO Seeding database.
INFO Running 2 registered package seeders.
Mypackage\Database\Seeders\UsersTableSeeder ................. RUNNING
Mypackage\Database\Seeders\UsersTableSeeder ................ 4 ms DONE
Mypackage\Database\Seeders\PostsTableSeeder ................. RUNNING
Mypackage\Database\Seeders\PostsTableSeeder ................ 2 ms DONE
Database\Seeders\DatabaseSeeder ............................ RUNNING
Database\Seeders\DatabaseSeeder ........................... 1 ms DONE
Every seeder that runs is named, the root one included. When nothing is registered the output is byte for byte what the framework prints.
Translations
The announcement line is translatable. Publish the language file to override it:
php artisan vendor:publish --tag=seedster-lang
The file lands in lang/vendor/seedster/en/seedster.php.
Laravel Support
| Laravel | Supported | Built in CI |
|---|---|---|
| 13 | Yes | Yes |
| 12 | Yes | Yes |
| 11 | Yes | No |
| 10 | Yes | No |
| 9 | Yes | No |
Laravel 9, 10 and 11 are still supported by the constraint in composer.json, but they are not built in CI. Every remaining release on those branches is covered by a security advisory with no patched version, so Composer will not resolve them under its default advisory policy.
Upgrading
From 1.0.x
Releases 1.0.0 and 1.0.1 bound the replacement command to the command.seed container key. Laravel stopped resolving db:seed through that key in Laravel 9, so on Laravel 9 and later the registered seeders were collected but never run. Upgrading fixes that, which means seeders your packages register will start running again on db:seed. Check what your installed packages register before seeding an environment you care about.
The public API is unchanged. The seed.handler binding, the register() and seeders() methods, the class names, and the command.seed key all behave as they did.
From eklundkristoffer/seedster
Swap the requirement and remove the old package. The container bindings are the same, so $this->app['seed.handler']->register(...) keeps working untouched. The only difference is the namespace, from Seedster\ to Jeremykenedy\LaravelSeedster\, which matters only if you imported the classes directly.
Testing
composer test
Check code style:
composer lint
Credits
- Jeremy Kenedy
- Kristoffer Eklund, author of the original seedster
License
The MIT License (MIT). See LICENSE for more information.