backpack/generators
Backpack Generators provides Artisan commands to scaffold Backpack admin panels: create CRUDs, models, controllers, requests, routes, and widgets in seconds, with sensible defaults and customizable stubs so you can build Laravel admin interfaces faster.
backpack/generators ships the scaffolding commands behind the Backpack CRUD workflow — most importantly backpack:crud. It is normally pulled in transitively by backpack/crud, so before installing anything check what you already have:
composer show backpack/generators
php artisan list | grep backpack
If it's missing (e.g. you use Backpack's UI packages selectively):
composer require backpack/generators --dev
Where to look first
php artisan backpack:crud --help — flags differ between Backpack 4/5/6, so trust the installed version over any blog post.app/Http/Controllers/Admin/ProductCrudController.php) — this is the file you'll actually live in.routes/backpack/custom.php — the command appends your route here; confirm the entry looks right before moving on.First use case: a CRUD in one command
# Model + migration exist already, or let the wizard create them
php artisan backpack:crud Product
The interactive wizard asks whether to create the model/migration if they're missing, then writes a ProductCrudController, a ProductRequest FormRequest, and a route entry. From there the daily loop is:
// setupListOperation()
CRUD::column('name');
CRUD::column('price');
// setupCreateOperation() / setupUpdateOperation()
CRUD::field('name')->type('text');
CRUD::field('price')->type('number');
Add ? to the end of the URL of an admin list page to reveal the field/column names you can paste back into these methods — that pairing (generate, browse ?, paste names) is the core of day-to-day Backpack work.
Generate-then-fill, never generate-and-ship. Treat the command as a first draft. The generated controller is deliberately thin: it extends CrudController, sets up the operation traits, and leaves all field definitions empty. Fill in setupListOperation, setupCreateOperation, setupUpdateOperation, and setupShowOperation in that order — the list view is what stakeholders see first.
Model-first vs. wizard-first. Two habits work well:
php artisan migrate, then php artisan backpack:crud Product. Backpack inspects the table and pre-populates sensible field types (email → email, text → textarea, dates → date), which saves a lot of time on wide tables.backpack:crud on a nonexistent model and accept the prompts to scaffold model + migration. Faster for throwaway admin panels, but you'll rewrite the migration anyway once real requirements land.Use --no-model (and friends) when integrating. If the model lives in a package, is a pivot, or you simply don't want a second one generated, skip that part of the scaffold. Same for the FormRequest when you already have validation elsewhere. Run --help for the exact flag names in your version.
Requests are the validation seam. The generated ProductRequest is a plain Laravel FormRequest — put authorize() and rules() there rather than in the controller. This is the cleanest place to add uniqueness (Rule::unique('products')->ignore($this->route('product'))) and conditional rules the DB introspection can't infer.
Pages for dashboards and static admin screens. php artisan backpack:page Dashboard generates a controller, a Blade view, and a route — the right tool for the "landing page after login" and for one-off admin screens that don't warrant a full CRUD. Keep them in the same Admin namespace as your CRUD controllers so middleware and route groups stay consistent.
Batch by domain, not by table. When adding a feature area (e.g. "Billing"), generate all its CRUDs in one sitting:
php artisan backpack:crud Invoice
php artisan backpack:crud Payment
php artisan backpack:crud Subscription
Then commit the generated skeleton before hand-editing. This gives you a clean diff to review and something to git checkout if a regeneration goes wrong.
Factor shared field definitions. Once three CRUDs share the same is_active toggle, created_at column, and SEO fields, extract them into a trait or a static helper (MyFields::timestamps()) that each setup*Operation() calls. Generated controllers are a good place to start this pattern, not to duplicate forever.
Customise the stubs for house style. If every controller in your org must use a specific base class or a declare(strict_types=1) header, publish/override the package stubs once instead of editing generated files every time. This is the main extension point the package offers, and it's worth the 20 minutes.
require-dev if you can, and never wire backpack:crud into a deploy script. Generated code that lands via CI is code nobody reviewed.routes/backpack/custom.php; if you use route caching, php artisan route:clear && php artisan route:cache or the new route 404s and you'll waste an hour.routes/backpack/custom.php must exist. If Backpack's route file isn't installed (fresh app, or you installed UI packages à la carte), route generation silently misbehaves or errors. Run the Backpack install step first.App\Models\… and App\Http\Controllers\Admin\…. If your app uses a non-standard root namespace or keeps models elsewhere, fix the stubs/config rather than hand-editing every file.git status clean before regenerating an existing CRUD.select, select_multiple, relationship, and enum field types after generation; the scaffold will have guessed text.SoftDeletes trait after generating, the controller won't have the trashed filter. Either pass the relevant flag up front or add the filter manually.created_at, user_id). Rename labels early (->label('Created')) before non-technical users see the list view.-vvv for debugging. When generation fails silently (permissions, missing directory), the verbosity flag usually surfaces the real error faster than reading the command source.CrudController with custom methods and $this->crud->addFilter(...) is the intended path. If you find yourself rewriting the controller wholesale, you probably want a plain Laravel resource controller plus a custom Backpack view instead.How can I help you explore Laravel packages today?