Laravel 13 dropped last week. The biggest takeaway is that it’s a "zero breaking changes" release for most. It’s mostly about modernizing the syntax and embracing AI.
1. PHP 8.3 is the New Floor
Laravel 13 officially requires PHP 8.3.
- Support for PHP 8.1 and 8.2 is gone.
- This lets the framework use typed constants and
json_validate()internally. - You get a small performance boost just by upgrading the runtime.
2. Attributes Everywhere
The biggest visual change is moving away from class properties to PHP Attributes. It's optional, but it makes models and jobs look much cleaner.
Old Way:
class User extends Model {
protected $table = 'users';
protected $fillable = ['name', 'email'];
}
New Way (Laravel 13):
#[Table('users')]
#[Fillable(['name', 'email'])]
class User extends Model {}
3. The First-Party AI SDK
Laravel now has a native AI SDK (laravel/ai). No more wrestling with multiple community packages to talk to OpenAI, Anthropic, or Gemini.
Features:
-
Provider Agnostic: Swap between OpenAI, Anthropic, and Gemini in
config/ai.phpwithout changing your app logic. - Unified API: One syntax for text, images, and audio.
Text Generation:
use Laravel\Ai\Facades\Ai;
$response = Ai::prompt('Explain quantum computing to a five year old');
echo $response->text;
Image Generation:
use Laravel\Ai\Image;
$image = Image::of('A futuristic city in the style of Van Gogh')
->landscape()
->generate();
$image->store('cities/future.png');
Creating an Agent:
Agents are classes that wrap instructions (system prompts) and tools.
namespace App\Ai\Agents;
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Promptable;
class SupportAgent implements Agent
{
use Promptable;
public function instructions(): string
{
return 'You are a helpful customer support assistant for our SaaS.';
}
}
// Usage:
$reply = (new SupportAgent)->prompt('How do I reset my password?');
4. Cache Management
A small but smart addition. You can now extend a cache item’s life without fetching the data first.
Old Way (Manual Refresh):
$value = Cache::get('session_data');
if ($value) {
Cache::put('session_data', $value, now()->addMinutes(30));
}
New Way (Laravel 13):
Cache::touch('session_data', 1800); // 1800 seconds
Just "touch" the key. It resets the expiration timer directly in the cache store (Redis/Memcached) without pulling the data into PHP memory.
5. JSON:API Resources (New in v13)
Laravel 13 introduces a dedicated JsonApiResource for strict spec compliance. It handles IDs, Types, and nesting automatically.
Setup:
php artisan make:resource PostResource --json-api
It uses a declarative style instead of the old toArray() manual nesting.
Comparison:
| Feature | Old Way (Manual) | New Way (v13 Native) |
|---|---|---|
| Structure | Manually define data, id, type. | Handled automatically. |
| Attributes | Mixed inside a single array. | Clean $attributes property. |
| Relations | Manual whenLoaded checks. |
Clean $relationships property. |
Example Code (v13):
use Illuminate\Http\Resources\JsonApi\JsonApiResource;
class PostResource extends JsonApiResource
{
public $attributes = ['title', 'content'];
public $relationships = ['author', 'comments'];
}
You can also use
toResource()directly on a model now, and Laravel will find the correct resource class for you.
My Take
If you’re on Laravel 12, don’t stress. The upgrade is mostly a dependency bump.
The "Attribute" syntax is the future—it’s more IDE-friendly and keeps configuration right where the logic is.
If you're starting a new project, go with 13 immediately to get that AI SDK and PHP 8.3 speed.
Top comments (0)