Skip to content
Back to skills

Laravel

ASecurity

Laravel is a PHP web framework for building full-stack applications and JSON APIs with Eloquent ORM, Blade views, the Artisan CLI, queues, events and Sanctum authentication. Use when a user asks to create a Laravel app, add models, migrations, controllers, form requests, API routes, queued jobs or token auth, run Artisan commands, or upgrade from Laravel 12 to 13.

  • 142 stars
  • 0 votes
  • 0 copies
  • 26 views
  • Added May 29, 2026
developmentgophpbashsqlreactvuenodegitapidatabase

Works with

  • terminal
  • cli
  • api

Security analysis

A96/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 2 files and shows the line behind each finding

Scanned October 4, 2026

npx -y skills add TerminalSkills/skills --skill laravel --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Laravel?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Laravel
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/terminalskills-laravel/badge)](https://www.skillsdirectory.com/skills/terminalskills-laravel)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: laravel
description: >-
  Laravel is a PHP web framework for building full-stack applications and JSON
  APIs with Eloquent ORM, Blade views, the Artisan CLI, queues, events and
  Sanctum authentication. Use when a user asks to create a Laravel app, add
  models, migrations, controllers, form requests, API routes, queued jobs or
  token auth, run Artisan commands, or upgrade from Laravel 12 to 13.
license: Apache-2.0
compatibility: "PHP 8.3+ and Composer; Node.js for the Vite frontend build (Laravel 13)"
metadata:
  author: terminal-skills
  version: "1.1.0"
  repository: https://github.com/laravel/framework
  category: development
  tags: ["php", "laravel", "eloquent", "artisan", "api"]
---

# Laravel — The PHP Framework for Web Artisans

## Overview

Laravel is a full-stack PHP framework. Laravel 13 (released March 2026, current line 13.x) requires PHP 8.3 or newer. It ships Eloquent (ORM), Blade (templates), Artisan (CLI), a queue system, events, scheduling and first-party packages such as Sanctum (API tokens and SPA cookies), Fortify (headless auth), Livewire, Horizon and Pint. New apps use SQLite by default, so `laravel new` works with no database server.

## Instructions

### Create and run an app

```bash
composer global require laravel/installer     # needs PHP 8.3+ and Composer
laravel new orders-api                         # prompts for a starter kit, tests, database
cd orders-api
npm install && npm run build
composer run dev                               # serves :8000, queue worker and Vite together
```

- Starter kits are React, Svelte, Vue (Inertia) and Livewire; all use Fortify for login, registration, 2FA and email verification. Breeze and Jetstream are not offered for new apps. Choose "none" for a plain API or Blade app.
- To use MySQL or PostgreSQL edit the `DB_*` values in `.env`, create the database, then run `php artisan migrate`.
- Create files with generators: `php artisan make:model Order -mfcr` (model, migration, factory, resource controller), `make:request`, `make:job`, `make:resource`, `make:policy`. `php artisan route:list` shows every route.

### Eloquent models

`$fillable`, `$hidden` and `casts()` on the model work in every version; Laravel 13 also accepts PHP attributes such as `#[Fillable([...])]` and `#[Table('...')]`. Define casts in a `casts()` method. Mark local scopes with `#[Scope]`.

```php
<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;

class Order extends Model
{
    use SoftDeletes;

    protected $fillable = ['user_id', 'reference', 'status', 'total_cents'];

    protected function casts(): array
    {
        return ['shipped_at' => 'datetime', 'meta' => 'array'];
    }

    public function items(): HasMany
    {
        return $this->hasMany(OrderItem::class);
    }

    #[Scope]
    protected function pending(Builder $query): void
    {
        $query->where('status', 'pending');
    }
}
// Order::pending()->with('items')->latest()->paginate(20);
```

### Validation and controllers

Put validation in a FormRequest (`php artisan make:request StoreOrderRequest`) and keep controllers thin. Hash passwords with the `hashed` cast on the User model (the default skeleton has it) or `Hash::make`.

```php
// app/Http/Controllers/OrderController.php
public function store(StoreOrderRequest $request)
{
    $order = $request->user()->orders()->create($request->validated());
    ProcessOrder::dispatch($order)->onQueue('orders');

    return new OrderResource($order);   // 201 for a newly created model
}
```

### API routes and Sanctum

`routes/api.php` does not exist in a fresh app. Run `php artisan install:api` to publish it, install Sanctum and add the migration, then migrate.

```bash
php artisan install:api
php artisan migrate
```

```php
// routes/api.php
Route::post('/sanctum/token', function (Request $request) {
    $request->validate(['email' => 'required|email', 'password' => 'required', 'device_name' => 'required']);
    $user = User::where('email', $request->email)->first();
    if (! $user || ! Hash::check($request->password, $user->password)) {
        throw ValidationException::withMessages(['email' => ['The provided credentials are incorrect.']]);
    }
    return $user->createToken($request->device_name, ['orders:read'])->plainTextToken;
});

Route::middleware('auth:sanctum')->group(function () {
    Route::apiResource('orders', OrderController::class);
});
```

The `User` model needs the `Laravel\Sanctum\HasApiTokens` trait. Clients send `Authorization: Bearer <token>`. Tokens are hashed in the database, so show `plainTextToken` once. For a first-party SPA do not use tokens: call `$middleware->statefulApi()` in `bootstrap/app.php`, set `SANCTUM_STATEFUL_DOMAINS`, fetch `/sanctum/csrf-cookie`, then POST `/login`.

### Queues

```php
<?php
namespace App\Jobs;

use App\Models\Order;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;

class ProcessOrder implements ShouldQueue
{
    use Queueable;

    public int $tries = 3;
    public int $backoff = 60;

    public function __construct(public Order $order) {}

    public function handle(): void
    {
        $this->order->process();
    }
}
```

Run `php artisan queue:work` (or let `composer run dev` do it). The default queue driver is `database`; use Redis plus Horizon for volume. Restart workers after a deploy with `php artisan queue:restart`.

### Laravel 13 notes (upgrading from 12)

- Update `laravel/framework` to `^13.0`, `laravel/tinker` to `^3.0`, `phpunit/phpunit` to `^12.0`, `pestphp/pest` to `^4.0`, then `composer global update laravel/installer`.
- The CSRF middleware is now `PreventRequestForgery` (it also checks `Sec-Fetch-Site`); `VerifyCsrfToken` remains as a deprecated alias.
- Cache has a `serializable_classes` option, `false` by default: list any PHP classes you store in cache.
- The skeleton sets session `serialization` to `json`; switching an existing app from `php` logs every user out.
- Default cache and session-cookie prefixes now use hyphens; set `CACHE_PREFIX` and `SESSION_COOKIE` to keep old names.
- Laravel Boost (`composer require laravel/boost --dev`, `php artisan boost:install`) gives agents project-aware tools and docs search.

## Examples

### Example 1: Token-protected orders API

**User request:** "Add an orders API to my Laravel app with login tokens, nothing for the browser."

```bash
php artisan install:api && php artisan make:model Order -mfcr --api
# edit the migration: user_id, reference, status, total_cents
php artisan migrate
php artisan test --compact
```

Add `HasApiTokens` to `User`, paste the token route and the `auth:sanctum` group from above into `routes/api.php`. Then `curl -H "Authorization: Bearer 1|k9Xa..." -H "Accept: application/json" http://localhost:8000/api/orders` returns a paginated JSON object; without the token it returns 401 `{"message":"Unauthenticated."}`.

### Example 2: Move PDF invoice generation off the request

**User request:** "Generating the invoice PDF takes 6 seconds. Make the order endpoint return immediately."

```bash
php artisan make:job GenerateInvoicePdf
```

Implement `ShouldQueue` with `$tries = 3`, call `GenerateInvoicePdf::dispatch($order)->onQueue('invoices');` in the controller and run `php artisan queue:work --queue=invoices,default`. The endpoint now answers in milliseconds, and failures are retried and listed by `php artisan queue:failed`.

## Guidelines

- Always `with()` relations you will loop over; call `Model::preventLazyLoading(! app()->isProduction())` in `AppServiceProvider::boot` to catch N+1 queries in development.
- Never edit a migration that has run in production; add a new one. Use `php artisan migrate --force` only in deploy scripts.
- Never set `$guarded = []` on models that take request input; validate and use `$request->validated()`.
- Keep `APP_DEBUG=false` and a real `APP_KEY` in production; run `php artisan config:cache route:cache view:cache` (or `php artisan optimize`) on deploy. After caching config, `env()` works only inside config files.
- Serve the `public/` directory as the web root, never the project root.
- Do not use Sanctum tokens for your own browser SPA; use its cookie mode. Reach for Passport only when you need a full OAuth2 server.
- Format with Pint (`vendor/bin/pint`) and test with Pest or PHPUnit (`php artisan test`).

Files in this skill

  • SKILL.md5 KB
  • _scores.json1.7 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.