Programming·Updated May 10, 2026·17 min read·👁 11.0K views

Laravel AI Prompts: Build Production PHP APIs & Web Apps Faster in 2026

John Allick· AI Researcher
📖 2,699 words
Quick Summary

Complete AI prompt library for Laravel developers. Covers Eloquent ORM, API Resources, Sanctum/Passport authentication, queues & jobs, Laravel Octane, Pest testing, and production deployment with Forge/Vapor — all with production-ready prompts.

#Laravel#PHP#Eloquent#Sanctum#Pest#AI Coding Prompts#Backend

Laravel in 2026: The PHP Framework for Web Artisans

Laravel 11 continues to be the most productive PHP framework — elegant syntax, powerful ORM, built-in queues, and a mature ecosystem. AI can dramatically accelerate Laravel development, but you need to specify modern patterns: Laravel 11's slim structure, Pest for testing, and Livewire or Inertia for full-stack if applicable. These prompts produce code that follows Laravel's conventions and passes a senior PHP developer's code review.

Picking the Right AI Model for Laravel Work

Laravel's "magic" — Eloquent, Facades, service container, route model binding — is easy to misuse in AI-generated code. Models that understand the conventions produce idiomatic Laravel; those that don't produce PHP that works but feels wrong to anyone who knows the framework.

ModelBest For (Laravel)Weak SpotWhen to Reach For It
Claude SonnetEloquent relationship design, service container architecture, complex queue systemsOccasionally suggests older Laravel 9 patterns for the new slim app structureDesigning the model relationship graph, reviewing Eloquent query optimization, planning the Observer/Event architecture
ChatGPT GPT-5.5Controller and form request boilerplate, Eloquent CRUD operationsUses Laravel 9 directory structure in Laravel 11 slim apps; ignores bootstrap/app.phpGenerating controllers from an API spec, writing Eloquent model factories
Gemini 3.5 FlashLaravel ecosystem research, package comparisons, Laravel 11 changelogLess depth on Eloquent's advanced features (subqueries, raw expressions)Researching the best Laravel package for a specific feature, comparing Livewire vs Inertia
CursorEloquent query completion with awareness of your model structureRoute facades sometimes generated incorrectlyWriting Eloquent queries when it can see your model definitions and relationships
GitHub CopilotBlade template generation, migration file boilerplateGenerates older migration syntax; misses Laravel 11 column modifiersCompleting Blade templates, writing migration files for new columns
GrokDirect comparison: Laravel vs Symfony, Pest vs PHPUnit trade-offsLess depth on Laravel Sanctum vs Passport nuancesGetting a direct opinion on whether Livewire or Inertia.js is right for a specific use case
DeepSeekBoilerplate Pest tests, Eloquent factory definitions, documentationLaravel 11's slim structure is often not understoodGenerating model factories, writing Pest test boilerplate

The key thing to verify in every AI-generated Laravel response: does it use the Laravel 11 slim application structure (bootstrap/app.php instead of app/Http/Kernel.php)? Laravel 11 removed the HTTP and Console Kernels in favor of a unified bootstrap file. Models trained on Laravel 9/10 generate code for the old structure. Always say "Laravel 11 with the slim app skeleton" explicitly.

1. API Controller with Form Requests & Resources

⌥ PROMPT
You are a senior Laravel 11 developer.

Build a complete API controller for the Task resource following Laravel best practices:

Files to generate:
- app/Http/Controllers/Api/V1/TaskController.php
- app/Http/Requests/Task/CreateTaskRequest.php
- app/Http/Requests/Task/UpdateTaskRequest.php
- app/Http/Resources/TaskResource.php
- app/Http/Resources/TaskCollection.php
- routes/api.php registration

Controller requirements:
- Route model binding with tenancy scope (Task must belong to auth user's organization)
- All write actions authorised via TaskPolicy
- Pagination: 25 per page default, configurable via ?per_page= (max 100)
- Response: TaskResource::collection() with pagination metadata

Form Request validation (CreateTaskRequest):
- authorize(): check user can create tasks in the project
- rules(): title required|min:3|max:255, priority in:low,medium,high,critical, due_at date|after:today
- messages(): custom human-readable error messages

TaskResource:
- Include: id, title, status, priority, due_at (formatted), assignee (nested UserResource), project_id
- Conditionally include: comments count (whenCounted), full description (when requested via ?include=description)

Use PHP 8.3 readonly properties and constructor promotion where appropriate.

2. Eloquent Models with Relationships & Scopes

⌥ PROMPT
You are an Eloquent ORM expert.

Design Eloquent models for a multi-tenant project management system:

Models: Organization, User, Project, Task, Comment

Task model requirements:
- SoftDeletes trait
- HasFactory trait with TaskFactory
- Casts: status → TaskStatus enum (PHP 8.1 backed enum), priority → PriorityEnum, due_at → datetime, custom_fields → array
- Relationships: belongsTo(Project), belongsTo(User, 'assigned_to'), hasMany(Comment), belongsTo(Organization)
- Local scopes: scopeOverdue(), scopeAssignedTo(User), scopeForOrganization(Organization), scopeWithStatus(TaskStatus)
- Global scope: OrganizationScope — automatically filters all queries to current tenant
- Accessors: isOverdue (bool), daysUntilDue (int|null) using Attribute::make()

Organization trait (add to all tenant models):
- Boot method: addGlobalScope(OrganizationScope::class)
- Static method: withoutTenantScope() for admin queries

Factory:
- States: overdue(), highPriority(), completed(), assignedTo(User $user)

Output: Task model, TaskStatus enum, OrganizationScope, TaskFactory with states.

3. Sanctum API Authentication

⌥ PROMPT
You are a Laravel Sanctum expert.

Implement Sanctum token authentication for a Laravel 11 API:

AuthController endpoints:
- POST /api/auth/login: validate credentials, issue named token (scoped abilities), return token + user
- POST /api/auth/logout: revoke current token
- POST /api/auth/refresh: revoke current, issue new token (token rotation)
- GET /api/auth/me: return authenticated user with organisation

Token abilities (scopes):
- read — GET endpoints only
- write — POST/PUT/PATCH
- admin — DELETE and admin endpoints
- Grant based on user role at login

Rate limiting:
- LoginThrottle middleware: 5 attempts per minute per IP
- Return 429 with Retry-After header

Security:
- Timing-safe password comparison (Hash::check is already timing-safe in Laravel)
- No user enumeration: identical 401 response for wrong email or password
- Log login events: user_id, ip_address, user_agent, success boolean, timestamp

Token expiration:
- Set expiration via Sanctum config: 'expiration' => 60 (minutes)
- Prune expired tokens: schedule('sanctum:prune-expired --hours=24')->daily()

Output: AuthController, LoginRequest, AuthService, and API route registration.

4. Queue Jobs & Events

⌥ PROMPT
You are a Laravel queues expert.

Design the event and queue architecture for a project management app:

Events and Listeners:
- TaskCreated → SendTaskCreationNotification (queued), UpdateProjectStats (queued)
- TaskAssigned → SendAssignmentEmail (queued), CreateInAppNotification (sync)
- TaskCompleted → UpdateCompletionStats, TriggerProjectCompletion (if all tasks done)

Job classes:

SendTaskCreationNotification:
- implements ShouldQueue, ShouldBeUnique (prevent duplicate emails if job retried)
- Queue: 'notifications'
- tries: 3, backoff: [60, 300, 900] (exponential)
- timeout: 30 seconds
- uniqueId(): return task ID (deduplicate per task)
- failed(): log to Slack, store in failed_notifications table

GenerateProjectReport:
- implements ShouldQueue
- Queue: 'heavy' (separate worker for CPU-intensive jobs)
- timeout: 300 seconds
- Chunk processing: process 500 tasks at a time with cursor pagination
- Progress: report progress via cache key for frontend polling

Scheduled tasks (app/Console/Kernel.php → routes/console.php in Laravel 11):
- SendOverdueTaskDigest: daily at 8am UTC per timezone
- CleanupSoftDeletedRecords: weekly (hard delete records soft-deleted 90+ days ago)
- PruneJobBatches: daily

Output: Event/Listener map, Job classes, scheduled task definitions.

5. Pest Feature Tests

⌥ PROMPT
You are a Pest PHP testing expert for Laravel 11.

Write Pest feature tests for the Task API endpoints:

Test setup:
- uses(RefreshDatabase::class) for DB reset per test
- Shared setup: beforeEach creates organization, admin user, member user, project
- actingAs($user, 'sanctum') for authentication

Tests (use Pest expect() API, not PHPUnit assertions):

test('member can create task in their organization project') → 201, task in DB, event dispatched
test('member cannot create task in another organization project') → 403
test('task creation requires valid due_at in future') → 422 with due_at field error
test('unauthenticated request returns 401') → 401 with www-authenticate header
test('list tasks returns only current organization tasks') → tenant isolation
test('admin can delete task, soft delete confirmed') → 204, deleted_at set in DB
test('rate limiter blocks 6th login attempt') → 429 with retry-after header

Fake facades: Event::fake(), Mail::fake(), Queue::fake()
Assert dispatched: Event::assertDispatched(TaskCreated::class, fn($e) => $e->task->id === $task->id)

Dataset example: dataset('invalid due dates', ['yesterday', 'invalid-date', '', null])

Output: full Pest test file with all test cases, beforeEach, and fake assertions.

6. Performance Optimisation

⌥ PROMPT
You are a Laravel performance engineer.

Audit and fix performance issues in this Laravel API controller:

[PASTE CONTROLLER CODE]

Fix:
1. N+1 queries: identify every relationship accessed in a loop, add with() or load() eager loading
2. withCount() / withSum(): replace collection->count() and collection->sum() called after loading
3. Chunking: replace Task::all()->each() with Task::chunk(500, fn) or cursor() for memory efficiency
4. Caching: identify pure reads that can use Cache::remember() with Redis (tag-based for invalidation)
5. DB indexes: list every column in where(), orderBy() calls — identify missing indexes
6. Avoid hydration: use ->select(['id','title','status']) + toArray() or pluck() instead of full model hydration for read-only endpoints

Laravel Octane consideration:
- Identify any static state or singleton state that would be unsafe under Octane (Swoole/FrankenPHP)
- Show which services need to be rebound per request

Output: fixed controller, a migration adding missing indexes, and Cache::tags() invalidation in the mutation methods.

8. Laravel Livewire Real-Time Component

⌥ PROMPT
You are a senior Laravel Livewire developer.

Build a Livewire v3 component for real-time task filtering and management:

Component: TaskManager
- Properties: $tasks (paginated collection), $search (string), $status (string), $priority (string), $sortBy (string), $sortDir (string)
- URL query string sync: #[Url] attribute on $search, $status, $priority — browser back/forward works
- Computed property: filteredTasks() — apply all filters via Eloquent scope, eager load assignee, paginate 25
- Real-time search: #[Reactive] on $search with 300ms wire:model.live.debounce.300ms
- Optimistic UI on toggle status: immediately update local state, then sync to server
- Livewire events: listen for TaskCreated, TaskDeleted from other components to refresh the list

Wire directives in Blade:
- wire:model.live.debounce.300ms="search"
- wire:click="sortBy('due_date')" with sort direction toggle
- wire:loading.attr="disabled" on the search input during network call
- Pagination: $this->paginationTheme = 'tailwind', {{ $tasks->links() }}

Server events via Echo + Pusher: broadcast('tasks', TaskUpdated::class) in the job, @script wire directive to update

Output: PHP Livewire component class, Blade template, and the TaskUpdated broadcast event class.

9. Laravel API with Inertia.js and Vue 3

⌥ PROMPT
You are a senior Laravel Inertia.js developer.

Set up a full-stack Laravel 11 + Inertia.js + Vue 3 application:

Authentication: Laravel Breeze with Inertia stack (Vue 3 + TypeScript)

Page component pattern:
- Laravel route → Controller → Inertia::render('Tasks/Index', [...data...])
- Vue page component receives typed props via defineProps<{ tasks: PaginatedTasks, filters: TaskFilters }>()
- TypeScript types generated from Ziggy routes and Laravel response shapes (use ziggy-js and @types/inertia)

Shared data: HandleInertiaRequests middleware → share: auth.user, flash messages, tenant config
Partial reloads: router.reload({ only: ['tasks'] }) for filter changes without full page load
Form handling: useForm() composable, form.post(route('tasks.store')), form.errors for validation display

File uploads with Inertia: useForm with files, track upload progress via form.progress

SPA-like feel: Link component for client-side navigation, preserveScroll on filter changes
TypeScript: define an inertia.d.ts with all shared props and page-specific prop types

Output: Laravel controller, Inertia middleware, Vue 3 page component with TypeScript, and the form component pattern.

End-to-End Workflow: REST API Feature with Tests

Shipping a complete Laravel API endpoint from database to test suite:

  1. Migration: "Create a Laravel migration for a comments table: id (ULID), task_id (foreign key CASCADE), user_id (foreign key SET NULL), content (text, max 5000), is_edited (boolean default false), deleted_at (softDeletes). Add index on [task_id, created_at]."
  2. Model (Prompt 2 variant): "Create Eloquent Comment model: BelongsTo Task, BelongsTo User, SoftDeletes trait, local scope scopeForTask, global scope for organization tenancy, appends 'is_owned_by' to JSON. Factory: CommentFactory with realistic content using Faker."
  3. Form Request: "Create StoreCommentRequest: authorize (user must belong to the task's organization), rules: task_id required exists:tasks,id, content required string min:1 max:5000, sanitize content in passedValidation using strip_tags."
  4. Controller + Resource (Prompt 1 variant): "Create CommentController: index (paginated, scoped to task), store (fire CommentCreated event, return CommentResource 201), update (only owner), destroy (only owner or admin, soft delete). CommentResource with conditional author fields."
  5. Tests (Prompt 6 variant): "Write Pest feature tests for CommentController: actingAs user, RefreshDatabase. Test 201 create, 422 validation, 403 cross-organization access, 403 editing other user's comment, 200 soft delete shows deleted_at."

Where AI Goes Wrong in Laravel

  • Laravel 9/10 directory structure in Laravel 11 projects. Laravel 11 removed app/Http/Kernel.php and app/Console/Kernel.php in favor of bootstrap/app.php. AI generates middleware registration in the old Kernel — it won't load in Laravel 11. Always specify "Laravel 11 with slim app skeleton."
  • Missing global scopes for multi-tenancy. AI-generated Eloquent models don't include global scopes for organization/tenant filtering. Every query on tenant-scoped models must filter by tenant — use a HasOrganization trait with addGlobalScope() to enforce this automatically.
  • N+1 queries in controller index methods. AI generates Task::all() or Task::paginate() without with() eager loading. The serializer or Resource then accesses $task->assignee inside a loop — one query per task. Specify "eager load all relations used in the Resource" in every controller prompt.
  • Incorrect Pest syntax. Pest v3 (current with Laravel 11) has slightly different API than Pest v2. AI occasionally mixes versions. Specify "Pest v3 with Laravel 11" and verify that refreshDatabase() and actingAs() calls match the current API.
  • Facades used in service class constructors. AI generates service classes that call Facades directly (Cache::get(), Queue::push()). This makes unit testing painful — you can't mock a Facade call without full application boot. Inject the underlying contracts instead (IlluminateContractsCacheRepository).

7. Good vs Bad Laravel Prompts

Task❌ Bad Prompt✅ Good Prompt
Controller"Build a task API in Laravel""Build a Laravel 11 API TaskController with route model binding (tenant-scoped), CreateTaskRequest form request with authorize() + rules(), TaskResource with conditional includes, TaskPolicy for authorization, and JsonResponse 201/204 status codes. PHP 8.3."
Eloquent"Query tasks from DB""Write an Eloquent query for tasks: eager load assignee and project (prevent N+1), apply scopeOverdue() and scopeForOrganization(), use withCount('comments'), paginate 25/page, and return TaskResource::collection(). Add the missing compound index migration."
Testing"Write tests for my controller""Write Pest feature tests for POST /api/tasks: RefreshDatabase, actingAs with Sanctum, Event::fake() + assert TaskCreated dispatched, test tenant isolation (403 for other org), test 422 validation with dataset of invalid inputs. Use expect() API."

Before You Prompt: Laravel Context Setup

Laravel 11 introduced a significantly slimmer application structure — bootstrap/app.php replaces the HTTP Kernel, middleware groups changed, and service provider auto-discovery handles most registration. AI trained on Laravel 9 or 10 generates the older structure that works but won't match your project layout. This block prevents the most common Laravel 11 version drift:

⌥ PROMPT
Context for all Laravel prompts in this session:
- Framework: Laravel 11 + PHP 8.3
- App structure: Laravel 11 slim app (bootstrap/app.php entry — NOT app/Http/Kernel.php)
  If generating middleware, register in bootstrap/app.php, not Kernel.php
- Auth: Sanctum for SPA/mobile token auth
  Passport only if specifically building an OAuth 2.0 server (99% of apps use Sanctum)
- Testing: Pest 3 with expect() API (NOT PHPUnit TestCase directly)
  Use RefreshDatabase or DatabaseTransactions trait
  Use model factories for all test data
- Eloquent: ALWAYS eager-load relationships with with() before returning collections
  Never return Eloquent collections without explicit eager loading
- Queues: Laravel queues with Redis driver, all jobs must be idempotent

The Pest 3 specification matters for test quality — Pest's expect($response->status())->toBe(201) reads as a natural assertion chain, while PHPUnit's $this->assertSame(201, $response->status()) adds cognitive overhead. Specifying Pest also triggers Pest-specific features like ->dataset() for parametrized tests, which dramatically reduces repetitive test boilerplate.

3 Common Mistakes When Prompting AI for Laravel

Mistake 1: Laravel 9/10 app structure in a Laravel 11 project

The most disorienting version drift in Laravel: asking for "middleware registration" in a Laravel 11 project gets middleware registered in app/Http/Kernel.php — a file that doesn't exist in Laravel 11's slim structure. The correct location is bootstrap/app.php using ->withMiddleware(). Specify "Laravel 11 slim app structure — register middleware in bootstrap/app.php, not Kernel.php." This affects service providers, middleware, routing, and exception handling registration.

Mistake 2: Eloquent lazy loading in production

Laravel enables lazy loading by default, so $task->project->name fires a SQL query on first access. In a loop over 50 tasks, that's 50 extra queries. Eloquent's Model::preventLazyLoading() throws an exception when you access a relationship without eager-loading in tests — which is why you should enable it. But the more important practice is specifying eager loading in every prompt: "use Task::with(['project:id,name', 'assignee:id,email'])->get() — never access relationships without eager loading."

Mistake 3: Passport when Sanctum is the right tool

Asking for "Laravel API authentication" without specifying the auth system often returns Laravel Passport configuration — a full OAuth 2.0 server with authorization codes, refresh tokens, and client credentials. Passport is the right choice if you're issuing tokens to third-party apps. For first-party SPA and mobile app authentication, Sanctum is simpler, ships with Laravel, requires no additional package setup, and handles both cookie-based SPA auth and token-based mobile auth. Specify "Laravel Sanctum for token authentication — not Passport."

Further Reading

Resources for AI-assisted Laravel and PHP development:

Generate a custom Laravel prompt → Try PromptPrepare free

Help & Answers

Frequently Asked Questions

John AllickAI Researcher· Updated May 10, 2026

John Allick is an AI researcher specializing in prompt engineering and large language model evaluation. He benchmarks models across ChatGPT, Claude, Gemini, Grok, and DeepSeek, focusing on practical techniques that produce reliable, production-ready outputs. Every guide on PromptPrepare is tested live on current model versions before publication.

✓ Expert-tested on live models✓ Updated May 10, 2026✓ Model-verified examples

Found this helpful?

Save it to your library or share with your team.

Keep Reading

Related Guides

Apply this guide instantly

Free AI prompt generator