Skip to main content
skill CX Codex

laravel-best-practices · asyrafhussin — Claude Code skill: Laravel 13 rules

A skill with 31 Laravel 13 rules covering architecture, Eloquent, controllers and validation. Useful when your agent writes PHP.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add AsyrafHussin/agent-skills --skill laravel-best-practices -a claude-code
Open on GitHub

What laravel-best-practices does

The skill hands your agent a Laravel 13 reference: 31 rules across 7 categories. Categories are ranked by priority — architecture and Eloquent are marked critical, controllers, validation and security high, performance and API design medium. Each rule carries a prefix like arch-, eloquent-, controller-, validation- or sec-, so the agent points at a specific rule instead of paraphrasing generic advice.

Inside are worked examples: a controller with a form request, the request class with rules and custom messages, a service class wrapping a transaction and firing an event, an Eloquent model with relationships, a scope and casts. The guide also covers service and action classes, DTOs, value objects, events, feature folders, eager loading, chunking, soft deletes and pruning. Laravel 13 additions include queue routing and vector search with pgvector.

The skill targets Laravel 13.x and PHP 8.3+. On an older branch some rules will not match what your framework actually does, so check the version before installing. The performance and API design categories have no rule files yet, which means the reference stays quiet on those topics.

What it helps with

  • move business logic into service and action classes
  • kill N+1 queries with eager loading
  • push validation into form requests with custom messages
  • define relationships and scopes on an Eloquent model
  • set up queue routing in Laravel 13

Example prompts for the agent

  • Create a controller and form request for storing a post following the laravel-best-practices skill
  • Check my Post model for N+1 queries and suggest eager loading
  • Move the post publishing logic into a service class with a transaction

How to install laravel-best-practices

1Skills CLI (Vercel)

npx skills add AsyrafHussin/agent-skills --skill laravel-best-practices -a claude-code

2Manually: put the files in place

~/.claude/skills/laravel-best-practices/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/laravel-best-practices/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about laravel-best-practices

How do I install laravel-best-practices in Claude?

Run npx skills add AsyrafHussin/agent-skills --skill laravel-best-practices -a claude-code. The skill file lands at ~/.claude/skills/laravel-best-practices/SKILL.md.

What does laravel-best-practices do?

It gives the agent 31 Laravel 13 rules in 7 categories: architecture, Eloquent, controllers, validation, security, performance and API design. Code samples cover controllers, form requests, services and models.

Which Laravel and PHP versions does it need?

The skill is written for Laravel 13.x and PHP 8.3+. On older versions some rules will not line up with what the framework supports.

Source text

SKILL.md · MIT
---
name: laravel-best-practices
description: Laravel 13 conventions and best practices. Use when creating controllers, models, migrations, validation, services, or structuring Laravel applications. Triggers on tasks involving Laravel architecture, Eloquent, database, API development, or PHP patterns.
license: MIT
metadata:
  author: Laravel Community
  version: "2.1.0"
  laravelVersion: "13.x"
  phpVersion: "8.3+"
---

# Laravel 13 Best Practices

Comprehensive best practices guide for Laravel 13 applications. Contains 31 rules across 7 categories for building scalable, maintainable Laravel applications.

## When to Apply

Reference these guidelines when:
- Creating controllers, models, and services
- Writing migrations and database queries
- Implementing validation and form requests
- Building APIs with Laravel
- Structuring Laravel applications

## Rule Categories by Priority

| Priority | Category | Impact | Prefix |
|----------|----------|--------|--------|
| 1 | Architecture & Structure | CRITICAL | `arch-` |
| 2 | Eloquent & Database | CRITICAL | `eloquent-` |
| 3 | Controllers & Routing | HIGH | `controller-`, `ctrl-` |
| 4 | Validation & Requests | HIGH | `validation-`, `valid-` |
| 5 | Security | HIGH | `sec-` |
| 6 | Performance | MEDIUM | `perf-` |
| 7 | API Design | MEDIUM | `api-` |

## Quick Reference

### 1. Architecture & Structure (CRITICAL)

- `arch-service-classes` - Extract business logic to services
- `arch-action-classes` - Single-purpose action classes
- `arch-repository-pattern` - When to use repositories
- `arch-dto-pattern` - Data transfer objects
- `arch-value-objects` - Encapsulate domain concepts
- `arch-event-driven` - Decouple with events and listeners
- `arch-feature-folders` - Organize by domain/feature
- `arch-queue-routing` - Centralized job queue routing (Laravel 13+)

### 2. Eloquent & Database (CRITICAL)

- `eloquent-eager-loading` - Prevent N+1 queries
- `eloquent-chunking` - Process large datasets
- `eloquent-query-scopes` - Reusable query logic
- `eloquent-model-events` - Use observers for side effects
- `eloquent-relationships` - Define relationships properly
- `eloquent-casts` - Automatic attribute casting
- `eloquent-accessors-mutators` - Transform attributes
- `eloquent-soft-deletes` - Safe deletion with recovery
- `eloquent-pruning` - Automatic cleanup of old records
- `eloquent-vector-search` - Semantic search with pgvector (Laravel 13+)

### 3. Controllers & Routing (HIGH)

- `controller-resource-controllers` - Use resource controllers
- `controller-single-action` - Single action invokable controllers
- `controller-resource-methods` - RESTful resource methods
- `controller-form-requests` - Use form requests
- `controller-api-resources` - Transform API responses
- `controller-middleware` - Apply middleware properly
- `controller-dependency-injection` - Inject dependencies

### 4. Validation & Requests (HIGH)

- `validation-form-requests` - Use form request classes
- `validation-custom-rules` - Create custom rules
- `validation-conditional-rules` - Conditional validation
- `validation-array-validation` - Validate nested arrays
- `validation-after-hooks` - Complex validation logic

### 5. Security (HIGH)

- `sec-mass-assignment` - Protect against mass assignment

### 6. Performance (MEDIUM)

No rule files exist yet for this category.

### 7. API Design (MEDIUM)

No rule files exist yet for this category.

## Essential Patterns

### Controller with Form Request

```php
<?php

namespace App\Http\Controllers;

use App\Http\Requests\StorePostRequest;
use App\Http\Requests\UpdatePostRequest;
use App\Models\Post;
use Illuminate\Http\RedirectResponse;

class PostController extends Controller
{
    public function store(StorePostRequest $request): RedirectResponse
    {
        // Validation happens automatically
        $validated = $request->validated();

        $post = Post::create($validated);

        return redirect()
            ->route('posts.show', $post)
            ->with('success', 'Post created successfully.');
    }

    public function update(UpdatePostRequest $request, Post $post): RedirectResponse
    {
        $post->update($request->validated());

        return redirect()
            ->route('posts.show', $post)
            ->with('success', 'Post updated successfully.');
    }
}
```

### Form Request Class

```php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StorePostRequest extends FormRequest
{
    public function authorize(): bool
    {
        return $this->user()->can('create', Post::class);
    }

    public function rules(): array
    {
        return [
            'title' => ['required', 'string', 'max:255'],
            'body' => ['required', 'string', 'min:100'],
            'category_id' => ['required', 'exists:categories,id'],
            'tags' => ['nullable', 'array'],
            'tags.*' => ['exists:tags,id'],
            'published_at' => ['nullable', 'date', 'after:now'],
        ];
    }

    public function messages(): array
    {
        return [
            'body.min' => 'The post body must be at least 100 characters.',
        ];
    }
}
```

### Service Class Pattern

```php
<?php

namespace App\Services;

use App\Models\User;
use App\Models\Post;
use App\Events\PostPublished;
use Illuminate\Support\Facades\DB;

class PostService
{
    public function __construct(
        private readonly NotificationService $notifications,
    ) {}

    public function publish(Post $post): Post
    {
        return DB::transaction(function () use ($post) {
            $post->update([
                'published_at' => now(),
                'status' => 'published',
            ]);

            event(new PostPublished($post));

            $this->notifications->notifyFollowers($post->author, $post);

            return $post->fresh();
        });
    }
}
```

### Eloquent Model

```php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Builder;

class Post extends Model
{
    use HasFactory;

    protected $fillable = [
        'title',
        'slug',
        'body',
        'category_id',
        'published_at',
    ];

    protected $casts = [
        'published_at' => 'datetime',
    ];

    // Relationships
    public function author(): BelongsTo
    {
        return $this->belongsTo(User::class, 'user_id');
    }

    public function category(): BelongsTo
    {
        return $this->belongsTo(Category::class);
    }

    public function tags(): BelongsToMany
    {
        return $this->belongsToMany(Tag::class)->withTimestamps();
    }

    // Scopes
    public function scopePublished(Builder $query): Builder
    {
        return $query->whereNotNull('published_at')
            ->where('published_at', '<=', now());
    }

    public function scopeByCategory(Builder $query, int $categoryId): Builder
    {
        return $query->where('category_id', $categoryId);
    }

    // Accessors & Mutators
    protected function title(): Attribute
    {
        return Attribute::make(
            set: fn (string $value) => ucfirst($value),
        );
    }
}
```

### Migration Best Practices

```php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id')->constrained()->cascadeOnDelete();
            $table->foreignId('category_id')->constrained()->cascadeOnDelete();
            $table->string('title');
            $table->string('slug')->unique();
            $table->text('body');
            $table->timestamp('published_at')->nullable();
            $table->timestamps();

            // Indexes for common queries
            $table->index(['user_id', 'published_at']);
            $table->index('category_id');
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('posts');
    }
};
```

### Eager Loading

```php
// N+1 Problem
$posts = Post::all();
foreach ($posts as $post) {
    echo $post->author->name;  // Query per post
}

// Eager loading — only 3 queries total
$posts = Post::with(['author', 'category', 'tags'])->get();
foreach ($posts as $post) {
    echo $post->author->name;  // No additional queries
}

// Nested eager loading
$posts = Post::with([
    'author.profile',
    'comments.user',
    'tags',
])->get();

// Constrained eager loading
$posts = Post::with([
    'comments' => fn ($query) => $query->latest()->limit(5),
])->get();
```

## How to Use

Read individual rule files for detailed explanations and code examples:

```
rules/arch-service-classes.md
rules/eloquent-eager-loading.md
rules/validation-form-requests.md
rules/_sections.md
```

Each rule file contains:
- YAML frontmatter with metadata (title, impact, tags)
- Brief explanation of why it matters
- Bad Example with explanation
- Good Example with explanation
- Laravel 13 and PHP 8.3 specific context and references

## Full Compiled Document

For the complete guide with all rules expanded: `AGENTS.md`

© Laravel Community · MIT · AsyrafHussin/agent-skills

Similar skills

Everything for Backend and APIs →

laravel-best-practices by other authors comes first.

From the same set12

php-best-practices A 51-rule guide for reviewing PHP 8.0–8.5 code against PSR standards, SOLID principles, and strict typing. Helps audit classes and adopt modern syntax. CX Codex +1 3,700installs react-vite-best-practices A skill with 23 rules for optimizing React apps built with Vite: build config, code splitting, HMR, assets, env variables and bundle analysis. Useful when an agent writes or reviews components. CX Codex +1 2,900installs laravel-inertia-react A skill that hands your agent ready rules for Inertia pages, useForm handling and shared data across Laravel and React. CX Codex +1 1,900installs clean-code-principles A skill for architecture review and code quality: SOLID, DRY, KISS, design patterns. Useful when refactoring or weighing design decisions. CX Codex +1 1,800installs typescript-react-patterns A skill with 33 TypeScript rules for React: props, hooks, events, refs, generics and context. Useful when the agent writes components and fights type errors. CX Codex +1 1,100installs api-design-patterns A skill with 38 REST API rules covering resources, errors, security, pagination and versioning. Useful when an agent writes or reviews endpoints. CX Codex +1 929installs laravel-testing Guides AI agents in writing Laravel 13 feature and unit tests with Pest 4 or PHPUnit 12, covering model factories and service mocks. CX Codex +1 907installs testing-best-practices A rule set for unit and integration tests and TDD: 34 rules in 7 categories, TypeScript with Jest and Vitest. Useful while writing tests or reviewing someone else's. CX Codex +1 899installs

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor