laravel-pro
Laravel guidance — Eloquent ORM, routing, queues, Blade/Livewire, and deploying PHP apps well.
Use this skill
- Read the full skill below — it’s all right here on this page. When you like it, hit copy.
- Paste it into a chat with Muse and add: “Please use this skill whenever I ask about laravel pro. Remember it for our future conversations.”
- That’s it. Muse follows the playbook for relevant tasks, and you approve anything it does.
The full skill
Overview
Laravel is PHP's most complete framework: Eloquent ORM, Blade templating, queues, scheduling, broadcasting, and first-party packages (Sanctum, Horizon, Scout) cover the full lifecycle of a web app. Modern Laravel pairs a robust backend with Livewire/Inertia for interactivity without a separate SPA. This skill covers building Laravel apps idiomatically — Eloquent without N+1s, queue discipline, and production PHP configuration.
When to use
- Building a PHP web app or API with Laravel.
- Eliminating N+1 queries or slow Eloquent code.
- Choosing between Blade, Livewire, and Inertia for the frontend.
- Setting up queues, scheduling, and Horizon for background work.
- Deploying PHP (opcache, workers, permissions) correctly.
- Building multi-tenant Laravel applications.
- Upgrading Laravel across major versions.
Core concepts
- Eloquent ORM. Active-record models with expressive relationships. Eager load with
with()to avoid N+1s; use query scopes for reusable filters; prefercursor()overget()for large datasets to avoid loading everything into memory. - Routing and controllers. Routes in
routes/web.php/routes/api.php; keep controllers thin with form requests handling validation/authorization (php artisan make:request). Resource controllers map REST conventions automatically. - Migrations and seeders. Version-controlled schema in
database/migrations; always write thedown()method; seed with factories for realistic dev data. - Queues and Horizon. Database/Redis queue drivers; jobs should be idempotent, retryable, and small. Horizon (Redis) gives a dashboard, supervision, and metrics for queue workers — use it in production.
- Task scheduling. The scheduler (
app/Console/Kernel.phporroutes/console.php) replaces most cron entries: one system cron hitsschedule:runevery minute, Laravel handles the rest. UsewithoutOverlapping()andonOneServer()for safety. - Frontend options. Blade for server-rendered pages, Livewire for reactive components without leaving PHP, Inertia for Vue/React SPAs driven by Laravel controllers. Pick one per surface; mixing all three creates confusion.
- Auth your way. Breeze/Jetstream scaffolds, Sanctum for API tokens and SPA auth, Passport only when you need a full OAuth2 server.
- Service container. The IoC container resolves dependencies via type-hinting; bind interfaces to implementations in providers for testability. Constructor injection keeps classes honest about their dependencies.
- Events and listeners. Decoupled side effects (
OrderPlaced→SendConfirmation,UpdateInventory); queue listeners for slow ones. Prefer explicit dispatch over model observers for business-critical flows. - Policies and Gates. Authorization logic in policies (
OrderPolicy@update), checked viaauthorize()or Blade@can— never inlineif ($user->id === ...)checks scattered through controllers. - Octane. Long-lived workers (FrankenPHP/RoadRunner/Swoole) for high-throughput Laravel — watch for state leaking between requests via singletons or static properties.
- Telescope. Local debug dashboard for queries, jobs, mail, and requests — invaluable in development; never enable it in production.
Practical workflow
-
Scaffold and configure.
laravel new shop; set.envper environment (never commit it); configure cache, session, and queue drivers for something real (redis/database, notsync/filein prod). -
Model the domain. Migrations first, then models with relationships, casts, and scopes; factories + seeders for dev data.
class Order extends Model { protected $casts = ['total' => 'decimal:2', 'placed_at' => 'datetime']; public function scopePaid($query) { return $query->where('status', 'paid'); } public function items() { return $this->hasMany(OrderItem::class); } } -
Build the API/web layer. Form requests for validation, API resources (
JsonResource) to shape responses (never return raw models), policies for authorization.- Resources keep response shapes stable and documented; transform dates, hide internals, include relationships deliberately.
-
Add background work. Dispatch jobs for anything slow; monitor with Horizon; schedule recurring tasks in the scheduler instead of raw cron.
ProcessOrder::dispatch($order)->onQueue('orders'); // scheduler: Schedule::command('invoices:send')->daily()->withoutOverlapping(); -
Optimize PHP for prod. Enable OPcache with timestamps off, run
config:cache,route:cache,view:cacheat deploy; set proper file permissions (storage/ bootstrap/cache writable by the web user). -
Test the layers. Feature tests hitting HTTP endpoints, unit tests for services, factories for fixtures; test queued jobs with
Queue::fake()and events withEvent::fake()where appropriate. -
Cache strategically.
Cache::remember()for expensive queries, tagged caches for group invalidation, and route/model caching via the*:cachecommands. -
Deploy. Build assets, run migrations in the release step, restart queue workers (
queue:restart) so they pick up new code, and warm caches.class OrderResource extends JsonResource { public function toArray(Request $request): array { return [ 'id' => $this->id, 'total' => $this->total, 'status' => $this->status, 'placed_at' => $this->placed_at->toIso8601String(), 'items' => OrderItemResource::collection($this->whenLoaded('items')), ]; } }
Common pitfalls
- N+1 queries —
with()eager loading on every relationship touched in loops/resources; watch with Laravel Debugbar or Telescope in dev. syncqueue driver in production — jobs run inline, making requests slow and failures invisible; use redis/database.- Forgetting
queue:restartafter deploys — long-lived workers keep running old code. - Uncached config/routes/views — skipping the
*:cachecommands leaves significant performance on the table. - Mass-assignment without
$fillable— either a MassAssignmentException or, worse, an open fillable list letting users setis_admin. - Storing uploads on local disk — use the
s3(object storage) disk; local disks don't survive multi-server deploys. - Debug mode on in prod (
APP_DEBUG=true) — exposes stack traces, env vars, and DB credentials. - Business logic in observers — hidden side effects firing on every save; prefer explicit events/jobs.
- No rate limiting on API routes — throttle sensitive endpoints; Laravel's throttle middleware is one line.
- Env caching confusion —
config:cachebakes env values; changing.envafter caching does nothing until re-cached. - Missing
APP_KEY— encrypted values become undecryptable; set it once per environment and never rotate it casually. - N+1 in Blade —
$order->itemsinside a@foreachis the same disease in a template; eager-load in the controller.