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

Filament Starter Kit Laravel Package

lyrihkaesa/filament-starter-kit

A Laravel Filament starter kit that scaffolds a ready-to-use admin panel with authentication, user and role management, settings, and reusable resources so you can launch business applications faster.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Laravel starter kit (application scaffold), not a drop-in library — you consume it once to bootstrap a project, then own the code. Treat upgrades like a template refresh, not a composer update.

Requirements after v1.2.0

  • PHP ^8.3 (hard requirement — upgrade your local/CI images first)
  • laravel/framework: ^13.0
  • Node 20+ for Vite/Tailwind, plus Playwright browsers if you run E2E

First five minutes

composer install
cp .env.example .env && php artisan key:generate
php artisan migrate --seed
npm install && npm run build
composer run dev          # serves app + vite + queue + logs

Then log in at /admin with the seeded user and immediately run the quality gates so you know your baseline is green before you touch anything:

./vendor/bin/pest
./vendor/bin/phpstan analyse
./vendor/bin/pint --test
./vendor/bin/rector --dry-run

Where to look first (in this order)

  1. composer.json — pin/verify the new constraints (laravel/framework ^13, laravel/pao, laravel/tinker ^3.0, pestphp/pest ^5).
  2. app/Models/ — the biggest mental shift in this release: models now use PHP attributes (#[Fillable], #[Guarded], #[Table], #[WithoutIncrementing]) instead of protected $fillable / $table properties.
  3. config/filesystems.php — check the uploads_tmp disk; it was deliberately retuned for Laravel 13.
  4. tests/Pest.php and phpunit.xml — Pest 5 bootstrap, PestSetList::CODING_STYLE presets.
  5. app/Actions/ — single-purpose invokable actions (e.g. RevokeOtherDevicesAction) are the kit's house style for business logic.
  6. app/Providers/Filament/ + app/Filament/ — panel config, Shield, Curator, Impersonate wiring.

Canonical first use case: scaffold auth + admin, add one Filament Resource for a real model, generate Shield permissions, write a Pest feature test for it. That exercises every layer (Eloquent attributes → policy → panel → test) in about an hour.

Implementation Patterns

Attribute-driven models. Configure Eloquent in the class declaration, not the body:

#[Table('posts')]
#[Fillable(['title', 'body', 'author_id'])]
class Post extends Model {}

Keep this consistent — mixing $fillable properties with #[Fillable] attributes across the codebase is the fastest way to lose an afternoon. Use #[Guarded([])] only where you genuinely want mass-assignment openness, and prefer #[Fillable] elsewhere so PHPStan can infer the shape.

Action classes for anything that isn't CRUD. The kit's convention is a single __invoke() per action, called from controllers, Livewire components, and Filament actions alike:

final class RevokeOtherDevicesAction
{
    public function __invoke(User $user, string $currentSessionId): void { /* ... */ }
}

This pays off in tests — you assert against the action directly instead of driving a browser.

Filament as the admin layer. Resources/Pages live under app/Filament/. Pair with Shield for RBAC (php artisan shield:generate --all after adding resources) and Curator for media fields. Impersonate is wired for support workflows — guard it behind a policy so it isn't available to every panel user.

Form Requests for validation, always. The kit ships request classes rather than inline $request->validate(). Filament forms should mirror those rules; keep a single source of truth by extracting shared rules into the request class and referencing them from the Filament schema where practical.

Testing pattern (Pest 5).

it('revokes other sessions', function () {
    $user = User::factory()->create();
    $this->actingAs($user);

    (new RevokeOtherDevicesAction)($user, session()->getId());

    expect($user->fresh()->sessions)->toHaveCount(1);
});
  • Feature tests over unit tests for anything touching sessions, policies, or Filament.
  • Use actingAs() + assertAuthenticatedAs(); the release explicitly fixed session assertions, so if you copied old assertions from a pre-1.2.0 fork, revisit them.
  • Filament/Livewire tests: livewire(ManageUsers::class)->assertCanSeeTableRecords(...). They're slower — keep them for authorization and form-shape regressions, not exhaustive CRUD paths.

CI quality gate ordering. Rector → Pint → PHPStan → Pest. Rector first because it rewrites assertions/coding style; Pint normalizes formatting so PHPStan diffs are readable; Pest last. Cache vendor/ and the PHPStan result cache between runs.

Upgrading an existing app built on the previous kit version. Don't merge blindly. Sequence: bump php + laravel/framework constraints → composer update -W → swap nunomaduro/pao for laravel/pao → composer dump-autoload → migrate models to attributes manually (one PR per domain, not one giant diff) → re-run php artisan filament:assets and php artisan shield:generate → run the gates. Keep the old model properties alongside the new attributes during the transition if you need a rollback path.

Dev loop. composer run dev runs server + Vite + queue + log tail concurrently; Playwright runs separately against a built app (npm run build first, or it tests stale assets).

Gotchas and Tips

PHP 8.3 is a hard floor. Any CI runner, Docker base image, or Herd/Valet box on 8.2 will fail at composer install with an opaque platform error. Bump images first; this is the #1 upgrade blocker.

laravel/pao is a fork/replacement, not an alias. Remove nunomaduro/pao from composer.json explicitly — leaving both installed produces duplicate class/service-provider registration and confusing "class already defined" errors. Then diff the API surface; abandoned-package replacements often rename namespaces and drop deprecated helpers. Grep your app for the old namespace before assuming a clean swap.

laravel/tinker ^3.0 is a major bump. If you have published config/tinker.php or custom Tinker commands registered as variables, republish and re-check. Config keys moved or were removed in v3.

Attribute models fail silently if the framework doesn't honor them. If any environment resolves an older laravel/framework (a forgotten platform config in composer.json, a stale lockfile in a branch), #[Fillable] is ignored and every create() throws MassAssignmentException — or worse, #[Guarded] is ignored and nothing throws at all. Verify with php artisan about in each environment after deploy.

Don't rename the uploads_tmp disk. The release specifically re-tuned it to avoid colliding with Laravel 13's route server disk. If you previously pointed it at local or renamed it to uploads, Curator uploads will start writing into a path Laravel 13 now claims. Keep the shipped name and path; override only the root, not the key.

PHPStan level max + Filament/Pest plugins. The pestphp/pest-plugin-phpstan extension infers types for functional tests, but you still need model docblocks (@property, @method) or you'll drown in "access to undefined property" errors on $user->fresh(). Also confirm the plugin version matches Pest 5 — mismatched plugin/phpstan.neon includes produce errors that look like your models are broken.

Rector's PestSetList::CODING_STYLE rewrites test assertions. Run --dry-run and read the diff before --write on a large legacy test suite; it will happily convert $this->assertX() into expect()->toX(), which can change failure message readability and occasionally change semantics on loose comparisons.

Session assertions in tests. Set SESSION_DRIVER=array in phpunit.xml and assert against $user->sessions in the DB, not against session()->getId() after a redirect. The RevokeOtherDevicesAction test fix in this release is a good reference implementation — copy it rather than inventing your own.

Shield permissions are cached. After adding a resource or changing a policy, run php artisan shield:generate --all and php artisan cache:forget spatie.permission.cache (or permission:cache-reset). The classic symptom: a super-admin suddenly gets 403 on a brand-new resource.

Impersonation must be policy-gated. It's convenient in dev and dangerous in prod. Wrap it so only users with an explicit permission can start impersonation, and log the start/stop events — the kit ships it enabled for panel access.

Playwright tests need a built frontend. Running E2E against npm run dev output is flaky (HMR mid-assertion). Build, serve, then test — or use two Playwright projects.

Default seeder credentials are for local only. Strip or gate the demo user seeder before the first deploy; starter kits routinely leak [email protected] / password into production.

Extension points worth knowing: AppServiceProvider for global Filament config, app/Filament/Resources/*/Schemas/ for form/table composition, Pest.php for shared test helpers/datasets, phpstan.neon for per-directory rule relaxations (prefer over lowering the global level), and rector.php for enforcing the attribute-model convention on future PRs via a custom rule.

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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource