gabriel2m/filament-starter-kit
A Laravel starter kit built for Filament that scaffolds admin panels with authentication, user and role management, and sensible defaults so you can skip the boilerplate and start building your app's core features right away.
This is a starter kit, not a package — you do not composer require it into an existing app. You either generate a fresh project from it or fork the repo, then live inside the resulting Laravel application. Everything below assumes that mental model: your day-to-day work is ordinary Filament resource authoring, and the kit's job is to have already done the boring parts.
Minimal steps
composer create-project gabriel2m/filament-starter-kit my-admin
cd my-admin
cp .env.example .env && php artisan key:generate
# set DB_* in .env, then:
php artisan migrate --seed
php artisan make:filament-user # or use the seeded admin
php artisan serve
If create-project fails (starter kits sometimes only ship as a plain repo), fall back to git clone + composer install + the same .env/migrate steps.
Where to look first, in this order
app/Providers/Filament/*PanelProvider.php — this is the nerve centre. Panel path, auth guard, middleware, colors, branding, navigation groups, and the auto-discovery of resources/pages/widgets all live here. Read it before writing a single resource.composer.json + composer.lock — confirm the Filament major (v3 vs v4) and the Laravel/PHP pins. Filament majors change form/table signatures; knowing which you're on prevents an hour of confused IDE errors.app/Filament/Resources/ — treat these as the house style template rather than inventing your own conventions.database/seeders/ and the policies — this tells you what the scaffold assumes about authorization, which is usually the thinnest part of any kit.First use case to prove the pattern
Build one throwaway CRUD resource end-to-end (php artisan make:filament-resource Post --generate) against a table you create yourself. It exercises the whole loop — migration, model, resource, form, table, policy, navigation — in about twenty minutes and tells you whether you've inherited a working foundation or a partially-wired one.
The core loop. Day to day you are writing three files per domain concept: an Eloquent model (+ migration), a Filament\Resources\XResource with form() and table() methods, and usually a policy. Filament's --generate flag will scaffold form and table schema straight from the DB columns; the generated code is a starting point you immediately edit, not a finished product.
Resource anatomy you'll touch constantly:
public static function form(Form $form): Form // Filament v3
public static function table(Table $table): Table
public static function getRelations(): array // relation managers
public static function getPages(): array // index/create/edit/view
If the kit ships Filament v4, form signatures shift to Schema (Filament\Schemas\Schema) rather than Form. Check the pinned version once, then forget it.
Relation managers are where admin panels earn their keep. Anything with a hasMany (order → line items, user → addresses) should get php artisan make:filament-relation-manager OrderResource items name, not a separate top-level resource. It keeps the operator on one screen and avoids navigation bloat.
Panel configuration as code. Branding, navigation groups, and access control belong in the panel provider, not scattered:
->brandName('Ops Console')
->path('admin')
->navigationGroups(['Sales', 'Settings'])
->authGuard('web')
For anything beyond a single audience, add a second panel (php artisan make:filament-panel reports) and gate it with ->authGuard()/canAccessPanel() on the user model. This is the cleanest way to separate "staff admin" from "customer back office" without middleware hacks.
Authorization. Default Filament resource access is wide open to any authenticated user unless you implement policies. Wire User::canAccessPanel() and per-model policies early, and register a Gate::before for a super-admin if the kit has roles. Retrofitting authorization onto ten resources is far more expensive than adding it before the first one.
Widgets and dashboards. php artisan make:filament-widget StatsOverview --stats-overview for KPI cards, --chart for trend charts. Keep widget queries lean — they run on every dashboard load for every user. Cache aggressively or use ->pollingInterval() deliberately rather than by default.
Seeding and fixtures. Extend the kit's seeders with realistic volume (thousands of rows, not tens) so you discover table N+1s and pagination issues in dev rather than in production. A seed dataset that fits on one page hides every performance problem you'll later have.
Local dev workflow. php artisan serve + npm run dev (if the kit bundles Vite assets) is sufficient; Livewire handles interactivity. Keep php artisan optimize:clear in muscle memory — cached configs and views are the single most common source of "my change did nothing."
It's a fork, not a dependency. There is no upgrade path. Upstream releases (v1.4.0 shipped with only a compare link, no narrative changelog) arrive as diffs you choose to adopt. Do a deliberate git diff v1.3.0..v1.4.0 on a throwaway branch before pulling anything in, and keep a short "our divergences from upstream" note in the repo. Merge cost compounds monthly.
Livewire asset mismatch after deploy is the classic silent failure: the panel renders but buttons and modals stop responding. Clear compiled views, run npm run build, and smoke-test one CRUD screen after every deploy. A green HTTP 200 proves nothing here.
Table queries are where admin panels fall over. Filament eagerly loads relationships for relationship columns; without ->modifyQueryUsing(fn ($q) => $q->with([...])) you get N+1s that only appear at real data volume. Enable query logging in staging and click through the heaviest listing.
File uploads will exhaust disk before anything else does. Cap ->maxSize() and image dimensions on FileUpload/SpatieMediaLibraryFileUpload components, and confirm queue workers are running if the kit configured queued conversions. Unbounded uploads are the most common cause of an admin panel taking down its own host.
The scaffold's auth is a starting point, not a permission model. Verify what a freshly seeded non-admin user can actually reach — over-broad operator access is a quiet, persistent problem in starter-kit-derived apps. Write an explicit test asserting a low-privilege user's navigation and 403s.
Extension points worth knowing: panel providers (multi-panel, middleware, tenancy via ->tenant(Team::class)), resource getNavigationBadge()/getNavigationGroup(), custom Page classes for dashboard-style screens, and Filament's ->action() closures for row-level operations. Before writing a custom Blade page, check whether a Filament action, bulk action, or header widget covers it — it usually does, with less maintenance.
Debugging toolkit: php artisan about (environment sanity), php artisan filament:cache-components only in production (it hides component discovery problems locally), Laravel Telescope or Debugbar for the N+1 hunt, and ->dd()/->dump() inline on table and form builders. When a field doesn't appear, it's almost always a policy/canView gate or a hidden() call, not a rendering bug.
Version pin discipline. Pin exact Laravel, Filament, Livewire, and PHP versions in composer.lock and record them in a one-paragraph ADR. A Filament major bump touching forms/tables/panels is a planned upgrade on a branch with a full manual pass over CRUD, auth flows, and uploads — never a routine composer update.
How can I help you explore Laravel packages today?