
Spatie Laravel Php
- 652 installs
- 88 repo stars
- Updated April 27, 2026
- spatie/guidelines-skills
spatie-laravel-php is a context-activated coding standards skill that applies Spatie's Laravel and PHP conventions—including PSR-12, typed properties, and Blade rules—when developers create, edit, or review Laravel backe
About
spatie-laravel-php is Spatie's comprehensive Laravel and PHP guideline skill from the guidelines-skills package (MIT license), auto-activating when agents touch .php or .blade.php files, routes, controllers, models, config, validation, migrations, or tests. The package ships 4 skills total; this one enforces PSR-1, PSR-2, and PSR-12, typed properties, constructor promotion, early returns, kebab-case URLs, plural resource controllers, array validation notation, and Blade formatting rules via references/spatie-laravel-php-guidelines.md. Install through Laravel Boost (composer require spatie/guidelines-skills --dev; php artisan boost:install) or skills.sh (npx skills add spatie/guidelines-skills). Developers reach for it to keep AI-generated Laravel code aligned with battle-tested Spatie conventions without repeating style instructions every prompt.
- spatie-laravel-php
- AI & Agent Building
- AI-coding skill
Spatie Laravel Php by the numbers
- 652 all-time installs (skills.sh)
- +34 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #1,482 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Jul 27, 2026 (Skillselion catalog sync)
npx skills add https://github.com/spatie/guidelines-skills --skill spatie-laravel-phpAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 652 |
|---|---|
| repo stars | ★ 88 |
| Last updated | April 27, 2026 |
| Repository | spatie/guidelines-skills ↗ |
How do you enforce Spatie Laravel PHP coding standards?
Helps with ai & agent building tasks.
Who is it for?
Laravel and PHP developers who want Spatie's production conventions applied automatically during AI-assisted coding and reviews.
Skip if: Teams on non-Laravel PHP frameworks or projects needing JavaScript, infrastructure, or database schema design guidance only.
When should I use this skill?
Agent works on Laravel or PHP files, or user asks to format, refactor, review, or align code with Spatie standards.
What you get
PSR-aligned PHP files, Laravel-native controllers and routes, consistent Blade templates, and convention-matched tests.
- Convention-aligned PHP files
- Formatted Blade templates
- Laravel-native route and controller code
By the numbers
- Package ships 4 guideline skills including spatie-laravel-php
- References 3 PSR standards: PSR-1, PSR-2, and PSR-12
Files
Spatie Laravel & PHP Guidelines
Overview
Apply Spatie's Laravel and PHP guidelines to keep code style consistent and Laravel-native.
When to Activate
- Activate this skill for any Laravel or PHP coding work, even if the user does not explicitly mention Spatie.
- Activate this skill when asked to generate, edit, format, refactor, review, or align Laravel/PHP code.
- Activate this skill when working on
.phpor.blade.phpfiles, routes, controllers, models, config, validation, migrations, or tests.
Scope
- In scope:
.php,.blade.php, Laravel conventions (routes, controllers, config, validation, migrations, tests). - Out of scope: JS/TS, CSS, infrastructure, database schema design, non-Laravel frameworks.
Workflow
1. Identify the artifact (controller, route, config, model, Blade, test, etc.). 2. Read references/spatie-laravel-php-guidelines.md and focus on the relevant sections. 3. Apply the core Laravel principle first, then PHP standards, then section-specific rules. 4. If a rule conflicts with existing project conventions, follow Laravel conventions and keep changes consistent.
Core Rules (Summary)
- Follow Laravel conventions first.
- Follow PSR-1, PSR-2, and PSR-12.
- Prefer typed properties and explicit return types (including
void). - Use short nullable syntax like
?string. - Use constructor property promotion when all properties can be promoted.
- One trait per line with separate
usestatements. - Prefer early returns and avoid
elsewhen possible. - Always use curly braces for control structures.
- Use string interpolation over concatenation.
- Happy path last: handle error conditions first.
Do and Don't
Do:
- Use kebab-case URLs, camelCase route names, and camelCase route parameters.
- Use tuple notation for routes:
[Controller::class, 'method']. - Use plural resource names for controllers (
PostsController). - Use array notation for validation rules.
- Use
config()helper and avoidenv()outside config files. - Add service configs to
config/services.php, not new files. - Use
__()for translations instead of@lang. - Use PascalCase for enum values.
Don't:
- Add docblocks when full type hints already exist.
- Use fully qualified classnames in docblocks.
- Use
finalorreadonlyby default. - Use
elsewhen early returns work. - Add spaces after Blade control structures.
- Write down methods in migrations, only up methods.
Examples
// Happy path last with early returns
if (! $user) {
return null;
}
if (! $user->isActive()) {
return null;
}
// Process active user...
// Short ternary
$name = $isFoo ? 'foo' : 'bar';
// Constructor property promotion
class MyClass {
public function __construct(
protected string $firstArgument,
protected string $secondArgument,
) {}
}@if($condition)
Something
@endifReferences
references/spatie-laravel-php-guidelines.md
Spatie Laravel & PHP Guidelines (Reference)
Table of Contents
- Core Laravel Principle
- PHP Standards
- Class Structure
- Type Declarations and Docblocks
- Control Flow
- Laravel Conventions
- Strings and Formatting
- Enums
- Comments
- Whitespace
- Validation
- Blade Templates
- Authorization
- Translations
- API Routing
- Testing
- Quick Reference
Core Laravel Principle
Follow Laravel conventions first. If Laravel has a documented way to do something, use it. Only deviate when you have a clear justification.
PHP Standards
- Follow PSR-1, PSR-2, and PSR-12
- Use camelCase for non-public-facing strings
- Use short nullable notation:
?stringnotstring|null - Always specify
voidreturn types when methods return nothing - Don't use
finalorreadonlyby default
Class Structure
- Use typed properties, not docblocks
- Use constructor property promotion when all properties can be promoted
- Use one trait per line
class MyClass {
use TraitA;
use TraitB;
public function __construct(
protected string $firstArgument,
protected string $secondArgument,
) {}
}Type Declarations and Docblocks
- Use typed properties over docblocks
- Specify return types including
void - Use short nullable syntax:
?TypenotType|null - Document iterables with generics:
/** @return Collection<int, User> */
public function getUsers(): CollectionDocblock Rules
- Don't use docblocks for fully type-hinted methods (unless description needed)
- Always import classnames in docblocks; never use fully qualified names:
use Spatie\Url\Url;
/** @return Url */- Use one-line docblocks when possible:
/** @var string */ - Most common type should be first in multi-type docblocks:
/** @var Collection|SomeWeirdVendor\Collection */- If one parameter needs docblock, add docblocks for all parameters
- For iterables, always specify key and value types:
/**
* @param array<int, MyObject> $myArray
* @param int $typedArgument
*/
function someFunction(array $myArray, int $typedArgument) {}- Use array shape notation for fixed keys, put each key on its own line:
/** @return array{
first: SomeClass,
second: SomeClass,
} */Control Flow
- Happy path last: handle error conditions first, success case last
- Avoid
else: use early returns instead of nested conditions - Separate conditions: prefer multiple if statements over compound conditions
- Always use curly brackets even for single statements
- Ternary operators: each part on its own line unless very short
// Happy path last
if (! $user) {
return null;
}
if (! $user->isActive()) {
return null;
}
// Process active user...
// Short ternary
$name = $isFoo ? 'foo' : 'bar';
// Multi-line ternary
$result = $object instanceof Model
? $object->name
: 'A default value';
// Ternary instead of else
$condition
? $this->doSomething()
: $this->doSomethingElse();Laravel Conventions
Routes
- URLs: kebab-case (
/open-source) - Route names: camelCase (
->name('openSource')) - Parameters: camelCase (
{userId}) - Use tuple notation:
[Controller::class, 'method'] - HTTP verb first for readability
- No leading slash unless URL is empty
Route::get('/', [HomeController::class, 'index'])->name('home');
Route::get('open-source', [OpenSourceController::class, 'index'])->name('openSource');
Route::post('users', [UsersController::class, 'store'])->name('users.store');Controllers
- Use plural resource names (
PostsController) - Stick to CRUD methods (
index,create,store,show,edit,update,destroy) - Extract new controllers for non-CRUD actions
// Instead of PostsController@favorite, extract:
class FavoritePostsController
{
public function store(Post $post)
{
request()->user()->favorites()->attach($post);
return response(null, 200);
}
public function destroy(Post $post)
{
request()->user()->favorites()->detach($post);
return response(null, 200);
}
}Views
- View files use camelCase:
openSource.blade.php
Configuration
- Files: kebab-case (
pdf-generator.php) - Keys: snake_case (
chrome_path) - Add service configs to
config/services.php, don't create new files - Use
config()helper, avoidenv()outside config files
// config/services.php
return [
'github' => [
'username' => env('GITHUB_USERNAME'),
'token' => env('GITHUB_TOKEN'),
],
];Artisan Commands
- Names: kebab-case (
delete-old-records) - Always provide feedback (
$this->comment('All ok!')) - Show progress for loops, summary at end
- Put output before processing an item (easier debugging):
$items->each(function (Item $item) {
$this->info("Processing item id `{$item->id}`...");
$this->processItem($item);
});
$this->comment("Processed {$items->count()} items.");Strings and Formatting
- Use string interpolation over concatenation:
$greeting = "Hi, I am {$name}.";Enums
- Use PascalCase for enum values:
enum Suit {
case Clubs;
case Diamonds;
case Hearts;
case Spades;
}- Class constants also use PascalCase:
class Session {
public const SessionTokenHeader = 'X-Session-Token';
}Comments
- Avoid comments; write expressive code instead
- When needed, use proper formatting:
// Single line with space after //
/*
* Multi-line blocks start with single *
*/- Refactor comments into descriptive function names
Whitespace
- Add blank lines between statements for readability
- Exception: sequences of equivalent single-line operations
- No extra empty lines between
{}brackets - Let code breathe; avoid cramped formatting
public function getPage($url)
{
$page = $this->pages()->where('slug', $url)->first();
if (! $page) {
return null;
}
if ($page['private'] && ! Auth::check()) {
return null;
}
return $page;
}Validation
- Use array notation for multiple rules (easier for custom rule classes):
public function rules()
{
return [
'email' => ['required', 'email'],
];
}- Custom validation rules use snake_case:
Validator::extend('organisation_type', function ($attribute, $value) {
return OrganisationType::isValid($value);
});Blade Templates
- Indent with 4 spaces
- No spaces after control structures:
@if($condition)
Something
@endifAuthorization
- Policies use camelCase:
Gate::define('editPost', ...) - Use CRUD words, but
viewinstead ofshow
@can('editPost', $post)
<a href="{{ route('posts.edit', $post) }}">Edit</a>
@endcanTranslations
- Use
__()function over@lang:
<h2>{{ __('newsletter.form.title') }}</h2>API Routing
- Use plural resource names:
/errors - Use kebab-case:
/error-occurrences - Limit deep nesting for simplicity:
/error-occurrences/1
/errors/1/occurrencesTesting
- Keep test classes in same file when possible
- Use descriptive test method names
- Follow the arrange-act-assert pattern
Quick Reference
Naming Conventions
- Classes: PascalCase (
UserController,OrderStatus) - Methods and variables: camelCase (
getUserName,$firstName) - Routes: kebab-case (
/open-source,/user-profile) - Config files: kebab-case (
pdf-generator.php) - Config keys: snake_case (
chrome_path) - Artisan commands: kebab-case (
php artisan delete-old-records)
File Structure
- Controllers: plural resource name +
Controller(PostsController) - Views: camelCase (
openSource.blade.php) - Jobs: action-based (
CreateUser,SendEmailNotification) - Events: tense-based (
UserRegistering,UserRegistered) - Listeners: action +
Listenersuffix (SendInvitationMailListener) - Commands: action +
Commandsuffix (PublishScheduledPostsCommand) - Mailables: purpose +
Mailsuffix (AccountActivatedMail) - Resources and Transformers: plural +
ResourceorTransformer(UsersResource) - Enums: descriptive name, no prefix (
OrderStatus,BookingType)
Migrations
- Do not write down methods in migrations, only up methods
Code Quality Reminders
- Use typed properties over docblocks
- Prefer early returns over nested if/else
- Use constructor property promotion when all properties can be promoted
- Avoid
elsestatements when possible - Use string interpolation over concatenation
- Always use curly braces for control structures
---
Source: https://spatie.be/guidelines
Related skills
How it compares
Pick this over generic PHP linters when you need opinionated Spatie Laravel conventions baked into agent context.
FAQ
Which file types trigger spatie-laravel-php?
spatie-laravel-php activates for .php and .blade.php work plus Laravel routes, controllers, models, config, validation, migrations, and tests. JavaScript, CSS, and infrastructure tasks are explicitly out of scope.
How do you install spatie-laravel-php?
Install spatie/guidelines-skills via Composer with Laravel Boost (composer require spatie/guidelines-skills --dev; php artisan boost:install) or run npx skills add spatie/guidelines-skills for skills.sh-compatible agents.