My Cursor Rules and AI Guidelines for Laravel Projects

Tutorial last revisioned on August 25, 2025

Let me share the guidelines for Cursor / Claude Code / Junie I use as "User rules". I'm planning to update this article with more changes in the future.

You can place these rules in Cursor Settings, like this:

You can also use the same rules as guidelines in other IDEs:

  • .junie/guidelines.md file in PhpStorm Junie AI
  • CLAUDE.md file in Claude Code

Of course, guidelines may change in the future, which I will also update in this article.

Last updated: August 25, 2025

## General code instructions
 
- Don't generate code comments above the methods or code blocks if they are obvious. Generate comments only for something that needs extra explanation for the reasons why that code was written
 
---
 
## PHP instructions
 
- In PHP, use `match` operator over `switch` whenever possible
- Use PHP 8 constructor property promotion. Don't create an empty Constructor method if it doesn't have any parameters.
- Using Services in Controllers: if Service class is used only in ONE method of Controller, inject it directly into that method with type-hinting. If Service class is used in MULTIPLE methods of Controller, initialize it in Constructor.
- Use return types in functions whenever possible, adding the full path to classname to the top in `use` section
 
---
 
## Laravel instructions
 
- For DB pivot tables, use correct alphabetical order, like "project_role" instead of "role_project"
- I am using Laravel Herd locally, so always assume that the main URL of the project is `http://[folder_name].test`
- **Eloquent Observers** should be registered in Eloquent Models with PHP Attributes, and not in AppServiceProvider. Example: `#[ObservedBy([UserObserver::class])]` with `use Illuminate\Database\Eloquent\Attributes\ObservedBy;` on top
- When generating Controllers, put validation in Form Request classes
- Aim for "slim" Controllers and put larger logic pieces in Service classes
- Use Laravel helpers instead of `use` section classes whenever possible. Examples: use `auth()->id()` instead of `Auth::id()` and adding `Auth` in the `use` section. Another example: use `redirect()->route()` instead of `Redirect::route()`.
 
---
 
## Use Laravel 11+ skeleton structure
 
- **Service Providers**: there are no other service providers except AppServiceProvider. Don't create new service providers unless absolutely necessary. Use Laravel 11+ new features, instead. Or, if you really need to create a new service provider, register it in `bootstrap/providers.php` and not `config/app.php` like it used to be before Laravel 11.
- **Event Listeners**: since Laravel 11, Listeners auto-listen for the events if they are type-hinted correctly.
- **Console Scheduler**: scheduled commands should be in `routes/console.php` and not `app/Console/Kernel.php` which doesn't exist since Laravel 11.
- **Middleware**: whenever possible, use Middleware by class name in the routes. But if you do need to register Middleware alias, it should be registered in `bootstrap/app.php` and not `app/Http/Kernel.php` which doesn't exist since Laravel 11.
- **Tailwind**: in new Blade pages, use Tailwind and not Bootstrap, unless instructed otherwise in the prompt. Tailwind is already pre-configured since Laravel 11, with Vite.
- **Faker**: in Factories, use `fake()` helper instead of `$this->faker`.
- **Policies**: Laravel automatically auto-discovers Policies, no need to register them in the Service Providers.
 
---
 
## Testing instructions
 
Use Pest and not PHPUnit. Run tests with `php artisan test`.
 
Every test method should be structured with Arrange-Act-Assert.
 
In the Arrange phase, use Laravel factories but add meaningful column values and variable names if they help to understand failed tests better.
Bad example: `$user1 = User::factory()->create();`
Better example: `$adminUser = User::factory()->create(['email' => '[email protected]'])`;
 
In the Assert phase, perform these assertions when applicable:
- HTTP status code returned from Act: `assertStatus()`
- Structure/data returned from Act (Blade or JSON): functions like `assertViewHas()`, `assertSee()`, `assertDontSee()` or `assertJsonContains()`
- Or, redirect assertions like `assertRedirect()` and `assertSessionHas()` in case of Flash session values passed
- DB changes if any create/update/delete operation was performed: functions like `assertDatabaseHas()`, `assertDatabaseMissing()`, `expect($variable)->toBe()` and similar.

Update: Filament v4 Rules

Also, since working with new Filament 4, I noticed AI generates quite a lot of v3-style code, although it says that it uses v4 docs. So, I created a new file with rules that I add specifically into Filament projects.

filament-v4.md

## Filament Version 4 Rules
 
List of important changes in Filament v4 vs Filament v3:
 
- Validation rule `unique()` has `ignoreRecord: true` by default, no need to specify it.
- Don't use full namespaces when referencing Filament classes like `Filament\Forms\Components\DatePicker`. Always put the namespaces in `use` section on top and use only classname instead of full path.
- If you create custom Blade files with Tailwind classes, you need to create a custom theme and specify the folder of those Blade files in theme.css.
- Table Filters have `->schema()` instead of `->form()`
- Table has `->toolbarActions()` instead of `->bulkActions()`

You can learn more from my video courses:


History of Updates

  • August 25, 2025: added a separate file for Filament v4 changes
  • August 6, 2025: added a section about Pest testing instructions
  • August 4, 2025: restructured PHP/Laravel separately, removed a few rules that weren't hallucinating anymore, and added a rule to use return types
  • July 10, 2025: added a section "Filament rules" with --view flag to be used in Filament 4
  • July 5, 2025: added five rules - how Observers should be registered, validation in Form Requests, "slim" Controllers with Service classes, using Laravel helpers like redirect() instead of classes in the use section, and use match over switch in PHP
  • July 1, 2025: added the info that I'm using Laravel Herd locally so website URL is http://[folder].test
  • July 1, 2025: removed all instructions related to php artisan make commands, as I switched to "Auto-run" mode (with restriction from deleting files, of course) where I don't even see/approve those commands
  • June 30, 2025: added "When generating Models and Migrations, do it in one Artisan command: php artisan make:model -m instead of doing separate make:model and make:migration" after I had to manually approve 2x commands (auto-run didn't work for some reason)
  • June 30, 2025: removed the instruction to use Filament 3 syntax, as Filament 4 Beta is out, and I will use v3/v4 depending on a project.
  • June 27, 2025: added "Don't create empty Constructor method if it doesn't have any parameters" after Cursor generated a Service class with empty and useless Constructor.
avatar
Alejandro Ismael Sanchez

I am trying Cursor for a new Filament v4 test project, and it is really, really annoying. Cursor keeps generating v3 code, does not follow the rules, etc. Other colleagues move really fast using Go, TypeScript, and so on. I’m an old guy who has been programming for years in PHP, Laravel, and Filament. Sorry for the rant.

avatar

This is indeed a problem with new versions of things!

You can however install Laravel boost and it helps a little bit with V4 syntax. It gets v4 documentation and uses it :)

Like our articles?

Become a Premium Member for $129/year or $29/month
What else you will get:
  • 83 courses
  • 96 long-form tutorials
  • access to project repositories
  • access to private Discord

Recent New Courses