---
title: "Novedades de Laravel: qué cambia en Laravel 14 y Laravel 13"
excerpt: "Las versiones de Laravel una por una: qué se rompe al actualizar, qué defaults cambian sin avisar y qué trae de nuevo cada mayor. Laravel 14 en desarrollo y Laravel 13, la versión actual."
date: "2026-03-04T10:00:00.000Z"
lastModified: "2026-10-04T15:00:00.000Z"
category: "Laravel"
tech_article: true
author:
  name: "angel cruz"
  picture: "/images/me/angel-cruz.png"
ogImage:
  url: "/images/open-graph/laravel-opengraph-image.png"
seo_title: "Novedades de Laravel 14 y 13: breaking changes y cómo actualizar"
seo_description: "Qué cambia en cada versión de Laravel: PHP 8.4 en Laravel 14, Queue::pause con nueva firma, el CSRF de Laravel 13, el AI SDK y la tabla de soporte."
---

**La versión actual de Laravel es la 13, lanzada el 17 de marzo de 2026 con PHP 8.3 como mínimo. La siguiente, Laravel 14, se desarrolla en la rama `master` de `laravel/framework`, pide PHP 8.4 y se espera para el primer trimestre de 2027.** Este artículo junta las dos: qué se rompe al actualizar a cada una, qué comportamientos cambian sin que toques nada y qué trae de nuevo cada mayor. Cuando sale una versión nueva, se suma aquí.

## Versiones de Laravel y soporte

Laravel lanza una versión mayor por año, alrededor del primer trimestre. Cada mayor recibe 18 meses de bug fixes y 2 años de parches de seguridad.

| Versión | PHP | Lanzamiento | Bug fixes hasta | Seguridad hasta |
|---------|-----|-------------|-----------------|-----------------|
| 11 | 8.2–8.4 | 12 mar 2024 | 3 sep 2025 | 12 mar 2026 |
| 12 | 8.2–8.5 | 24 feb 2025 | 13 ago 2026 | 24 feb 2027 |
| 13 | 8.3–8.5 | 17 mar 2026 | Q3 2027 | 17 mar 2028 |
| 14 | 8.4+ | Q1 2027 (previsto) | Q3 2028 | Q1 2029 |

Las filas de 11 a 13 salen de la tabla de la política de soporte de las notas de lanzamiento oficiales. Las fechas de Laravel 14 son previsiones: la de lanzamiento es la que publica Laravel News, y las de soporte resultan de aplicar los 18 meses y los 2 años a ese trimestre.

Laravel 11 ya no recibe ningún parche. Laravel 12 solo recibe parches de seguridad, hasta el 24 de febrero de 2027. Si tu aplicación está en cualquiera de las dos, el salto que toca es a 13, y Laravel 14 viene después.

## Laravel 14: qué se rompe al actualizar

Laravel 14 todavía no está lanzado. Lo que sigue está en la rama `master` del repositorio, contrastado contra la rama `13.x`. Es una rama de desarrollo, así que pueden entrar más cambios antes del lanzamiento; los que ya están mergeados rara vez se revierten.

### PHP 8.4 como mínimo

El `composer.json` de `master` declara `"php": "^8.4"`, frente al `"php": "^8.3"` de la rama `13.x`. Es el único cambio que afecta a todo el mundo por igual.

```bash
# Comprueba el runtime antes de cualquier otra cosa
php -v
```

Si tu servidor corre PHP 8.3, te quedas en Laravel 13 hasta que actualices el runtime, y Laravel 13 tiene bug fixes hasta Q3 2027.

El salto arrastra al resto de las dependencias. En `master`, los componentes de Symfony pasan a `^8.1.0` (console, http-foundation, http-kernel, routing, mailer, mime, process, finder, uid, var-dumper y error-handler), y Symfony 8 también pide PHP 8.4. En desarrollo, `orchestra/testbench-core` sube a `^12.0.0` y PHPUnit queda como `^11.5.50 || ^12.5.8 || ^13.0.3`. Si mantienes un paquete con matriz de CI, esos tres son los que te van a romper el pipeline primero.

### Queue::pause() cambia el orden de los argumentos

Este cambio no falla al cargar la aplicación: falla pausando la cola equivocada. En Laravel 13 la firma era `pause($connection, $queue)`, con los dos argumentos obligatorios. En `master` es `pause($queue, $connection = null)`, con la conexión opcional.

```php
// Laravel 13
Queue::pause('redis', 'emails');
Queue::pauseFor('redis', 'emails', 60);
Queue::resume('redis', 'emails');
Queue::isPaused('redis', 'emails');

// Laravel 14
Queue::pause('emails');                 // usa la conexión por defecto
Queue::pause('emails', 'redis');        // o la que le pases
Queue::pauseFor('emails', 60, 'redis'); // el TTL ahora va en el medio
```

Con el orden viejo, `Queue::pause('redis', 'emails')` pausa una cola llamada `redis` en la conexión `emails`, que probablemente no exista. El worker sigue trabajando, la cola que querías detener sigue consumiendo y los logs no dicen nada. Busca cada llamada a mano:

```bash
grep -rnE "Queue::(pause|pauseFor|resume|isPaused)\(" app/ routes/ tests/
```

`pauseAll()` y `resumeAll()` se quedan igual: no reciben argumentos.

### findOr() con un array de IDs

En Laravel 13, `findOr()` con un array invocaba el callback solo si el resultado era `null`, y una colección vacía o incompleta no lo es. En `master` el callback se dispara si no se encontraron todos los IDs que pediste.

```php
// IDs 1 y 2 existen, el 999 no
User::findOr([1, 2, 999], fn () => 'faltan usuarios');

// Laravel 13: devuelve la colección con los dos usuarios encontrados
// Laravel 14: ejecuta el callback y devuelve 'faltan usuarios'
```

La comparación es contra `array_unique($id)`, así que los IDs repetidos no cuentan de más. Si tu código dependía de recibir el subconjunto encontrado, cámbialo a `find()` y comprueba el conteo tú.

## Laravel 14: defaults que cambian sin que toques nada

Esto es código que compila, pasa los tests y se comporta distinto en producción.

### chunk() y lazy() ya no mutan el query builder

En Laravel 13, `chunk()` y `lazy()` aplicaban `offset()` y `limit()` sobre la propia instancia del builder. Al terminar, el builder quedaba con el último `limit` y `offset` del recorrido, y reutilizarlo devolvía resultados recortados. En `master` ambos métodos clonan el builder antes de iterar.

```php
$query = User::where('active', true);

$query->chunk(100, function ($users) {
    // procesa
});

// Laravel 13: el builder arrastra offset/limit del último chunk
// Laravel 14: el builder sigue intacto y el count es el real
$query->count();
```

Si alguna parte de tu código compensaba la mutación reseteando límites a mano, ese apaño ahora sobra.

### MassPrunable borra también los modelos soft deleted

El trait `MassPrunable` de `master` añade `withTrashed()` a la query cuando el modelo usa soft deletes, antes del `forceDelete()`. En Laravel 13 ya hacía `forceDelete()`, pero sin `withTrashed()`, así que los registros con `deleted_at` quedaban fuera y sobrevivían al `model:prune`.

En Laravel 14, el mismo modelo y el mismo `prunable()` borran filas que antes se quedaban. Si tu `prunable()` filtra por `created_at` y tienes años de registros soft deleted, el primer `model:prune` tras la actualización va a borrar mucho más de lo habitual.

```bash
# Mira el alcance antes de dejarlo suelto
php artisan model:prune --pretend
```

### Cache::has() y Cache::forget() aceptan arrays

En Laravel 13, `Cache::has(['a', 'b'])` pasaba el array a `get()` y el resultado no significaba lo que parecía. En `master`, `has()` con un array resuelve por `many()` y devuelve `true` solo si están todas las claves; `forget()` con un array delega en `deleteMultiple()`.

```php
Cache::has(['user:1', 'user:2']);    // true solo si están las dos
Cache::forget(['user:1', 'user:2']); // borra las dos
```

Si tenías un helper propio que iteraba las claves para simular esto, ya puedes tirarlo.

## Laravel 14: novedades ya mergeadas

**Rutas con el método HTTP QUERY.** `QUERY` entra en los verbos del router y aparece `Route::query()`:

```php
Route::query('/search', SearchController::class);
```

**`$user->authorize()`.** El contrato `Illuminate\Contracts\Auth\Access\Authorizable` declara `authorize($ability, $arguments = [])` junto a `can()`, así que la autorización con excepción se le pide al propio usuario:

```php
$user->authorize('update', $post);
```

**Contexto en `report()`.** Los tres helpers aceptan un array de contexto que llega al handler de excepciones:

```php
report($e, ['order_id' => $order->id]);
report_if($failed, $e, ['attempt' => $attempt]);
report_unless($ok, $e, ['payload' => $payload]);
```

**`whereKey()` acepta subqueries.** Además de un ID, un array o un modelo, recibe un `Closure`, un query builder o una relación, y los resuelve con `whereIn`. La firma pasa a `whereKey(mixed $id, string $boolean = 'and', bool $not = false)`:

```php
$posts = Post::whereKey(fn ($query) => $query
    ->select('post_id')
    ->from('featured_posts')
)->get();
```

**`Storage::fake('ondemand')` para discos on-demand.** `FilesystemManager::build()` devuelve `$this->disks['ondemand']` si ya existe, en lugar de resolver siempre un disco nuevo. Como `Storage::fake()` registra el disco con el nombre que le pasas, el código que crea discos al vuelo se vuelve testeable:

```php
Storage::fake('ondemand');

// Dentro del código bajo prueba, esto ahora devuelve el disco falso
Storage::build(['driver' => 's3', 'bucket' => 'facturas']);
```

### Cómo preparar la actualización a Laravel 14

1. Sube el runtime a PHP 8.4. Laravel 13 soporta 8.3, 8.4 y 8.5, así que puedes mover PHP sin tocar el framework.
2. Haz inventario de las llamadas afectadas: `Queue::pause` y familia, `findOr` con arrays, `Cache::has` con arrays y los `chunk`/`lazy` cuyo builder se reutiliza después.
3. Corre `model:prune --pretend` en los modelos con soft deletes.
4. Revisa la matriz de CI de tus paquetes: Symfony 8.1, testbench 12 y PHPUnit 11.5/12.5/13.

## Laravel 13: qué se rompe al actualizar desde Laravel 12

La guía oficial estima unos 10 minutos para la mayoría de las aplicaciones. Marca como impacto alto tres cosas: las dependencias, el instalador y la protección contra request forgery.

### Dependencias y PHP 8.3

Laravel 13 requiere PHP 8.3. En `composer.json`:

```text
laravel/framework  → ^13.0
laravel/boost      → ^2.0
laravel/tinker     → ^3.0
phpunit/phpunit    → ^12.0
pestphp/pest       → ^4.0
```

Si creas proyectos con el instalador, actualízalo también: `composer global update laravel/installer`, o la versión de Herd si usas la que trae Herd.

### VerifyCsrfToken pasa a llamarse PreventRequestForgery

El middleware de CSRF cambia de nombre y además verifica el origen de la petición con el header `Sec-Fetch-Site`. `VerifyCsrfToken` y `ValidateCsrfToken` quedan como alias deprecados, así que nada se rompe el primer día, pero las referencias directas conviene cambiarlas, sobre todo en tests:

```php
use Illuminate\Foundation\Http\Middleware\PreventRequestForgery;

// Laravel 12
->withoutMiddleware([VerifyCsrfToken::class]);

// Laravel 13
->withoutMiddleware([PreventRequestForgery::class]);
```

### La caché deja de deserializar objetos arbitrarios

La configuración de `cache` trae una opción nueva, `serializable_classes`, en `false`. Si guardas objetos PHP en caché, tienes que listar las clases permitidas o pasar a guardar arrays:

```php
'serializable_classes' => [
    App\Data\CachedDashboardStats::class,
],
```

### upsert() exige uniqueBy en MySQL y MariaDB

`upsert()` lanza `InvalidArgumentException` si `uniqueBy` va vacío, también en MySQL y MariaDB, donde ese valor se ignora porque el motor usa los índices de la tabla. Antes generaba SQL inválido.

### Cambios de bajo impacto

- **Prefijos de caché, Redis y cookie de sesión**: los valores por defecto pasan de guion bajo a guion (`laravel-cache-` en vez de `laravel_cache_`). Solo te afecta si tu configuración no los define; para conservar los viejos, fija `CACHE_PREFIX`, `REDIS_PREFIX` y `SESSION_COOKIE` en `.env`.
- **Sesión en JSON**: el esqueleto nuevo pone `serialization` en `json` en `config/session.php`. Si sincronizas ese archivo con el esqueleto, todas las sesiones activas se invalidan; para conservarlas, deja `php`.
- **`Container::call()`** respeta el default `null` de un parámetro nullable sin binding, igual que la inyección por constructor.
- **MySQL `DELETE` con `JOIN`** incluye `ORDER BY` y `LIMIT`. En MySQL, y en MariaDB anterior a 11.8.1, eso puede lanzar `QueryException` donde antes había un borrado sin límite.
- **Rutas con dominio** se evalúan antes que las rutas sin dominio.
- **Eventos de cola**: `JobAttempted::$exceptionOccurred` pasa a `$exception` (el objeto o `null`), y `QueueBusy::$connection` pasa a `$connectionName`.
- **Pivots polimórficos** con clase propia: el nombre de tabla inferido pasa a plural. Define `$table` si dependías del singular.
- **Colecciones serializadas** (en jobs, por ejemplo) restauran las relaciones eager-loaded.
- **Vistas de paginación**: `pagination::default` pasa a `pagination::bootstrap-3`, y `pagination::simple-default` a `pagination::simple-bootstrap-3`.
- **`Str` factories** se resetean entre tests.
- **`array_first()` y `array_last()`**: Laravel 13 depende de `symfony/polyfill-php85`, que define esas funciones globales en PHP < 8.5 y choca con helpers viejos del mismo nombre. Usa `Arr::first()`.

### Cómo actualizar a Laravel 13

1. Comprueba que el servidor corre PHP 8.3 o superior.
2. Actualiza las dependencias de `composer.json` y corre `composer update`.
3. Busca referencias a `VerifyCsrfToken` y objetos PHP guardados en caché.
4. Repasa la lista de bajo impacto contra tu código.

Si tienes [Laravel Boost](https://github.com/laravel/boost) `^2.0` instalado, el comando `/upgrade-laravel-v13` guía la actualización desde Claude Code, Cursor, OpenCode, Gemini o VS Code. [Laravel Shift](https://laravelshift.com/) la automatiza con un pull request.

## Laravel 13: qué trae de nuevo

### Laravel AI SDK

El paquete de primera parte [`laravel/ai`](https://laravel.com/docs/13.x/ai-sdk) da una API única, agnóstica del proveedor, para generación de texto, agentes con tool-calling, embeddings, audio, imágenes y vector stores. Se instala aparte con `composer require laravel/ai`.

```php
use App\Ai\Agents\SalesCoach;

$response = SalesCoach::make()->prompt('Analiza esta transcripción de ventas...');

return (string) $response;
```

### Búsqueda vectorial con pgvector

El query builder trae cláusulas de similitud vectorial sobre PostgreSQL con `pgvector`, y los embeddings se generan desde un string:

```php
$documents = DB::table('documents')
    ->whereVectorSimilarTo('embedding', 'Las mejores bodegas de la Rioja')
    ->limit(10)
    ->get();
```

Si usas MariaDB, [la búsqueda vectorial en Laravel con MariaDB](/post/laravel-mariadb-vector-busqueda-semantica) tiene los requisitos y el SQL que se genera en cada motor.

### JSON:API, queue routing, attributes y Cache::touch()

- **Recursos JSON:API** de primera parte: serialización, inclusión de relaciones, sparse fieldsets, links y los headers correctos.
- **Queue routing por clase**: la conexión y la cola de un job se definen en un solo sitio.

  ```php
  Queue::route(ProcessPodcast::class, connection: 'redis', queue: 'podcasts');
  ```

- **Más PHP attributes**: `#[Middleware]` y `#[Authorize]` en controladores, `#[Tries]`, `#[Backoff]`, `#[Timeout]` y `#[FailOnTimeout]` en jobs, y otros en Eloquent, eventos, notificaciones, validación y testing. Las propiedades de siempre siguen funcionando.
- **`Cache::touch()`** extiende el TTL de un item sin leerlo ni volver a guardarlo.

Para lo que viene después de actualizar, del deploy al monitoreo, está [Laravel en producción](/laravel-produccion).

---

## Preguntas frecuentes

### ¿Cuál es la última versión de Laravel?

Laravel 13, lanzado el 17 de marzo de 2026. Laravel 14 está en desarrollo y se espera para el primer trimestre de 2027.

### ¿Qué versión de PHP necesita cada versión de Laravel?

Laravel 13 necesita PHP 8.3 y soporta hasta 8.5. Laravel 14 pide PHP 8.4 como mínimo, atado a Symfony 8. Laravel 12 soporta de 8.2 a 8.5.

### ¿Cuándo sale Laravel 14?

La previsión es el primer trimestre de 2027, siguiendo el ciclo anual. Laravel 13 salió el 17 de marzo de 2026 y Laravel 12 el 24 de febrero de 2025.

### ¿Cuáles son los breaking changes de Laravel 14?

Los mergeados hasta ahora: PHP 8.4 mínimo, el nuevo orden de argumentos en `Queue::pause()` y sus hermanos, `findOr()` con arrays invocando el callback cuando faltan IDs, `chunk()` y `lazy()` sin mutar el builder, `MassPrunable` incluyendo los modelos soft deleted, y `Cache::has()`/`Cache::forget()` tratando los arrays como tales.

### ¿Qué cambia entre Laravel 12 y Laravel 13?

PHP 8.3 como mínimo, el middleware de CSRF renombrado a `PreventRequestForgery`, la caché que ya no deserializa objetos arbitrarios y `upsert()` exigiendo `uniqueBy`. Lo nuevo: el AI SDK, búsqueda vectorial, recursos JSON:API, queue routing y más attributes.

### ¿Laravel 12 sigue soportado?

Solo con parches de seguridad, hasta el 24 de febrero de 2027. Los bug fixes terminaron el 13 de agosto de 2026.

### ¿Hasta cuándo tengo soporte si me quedo en Laravel 13?

Bug fixes hasta el tercer trimestre de 2027 y parches de seguridad hasta el 17 de marzo de 2028.

---

## Referencias

- [Release Notes y política de soporte, documentación oficial de Laravel 13](https://laravel.com/docs/13.x/releases)
- [Upgrade Guide de Laravel 13, documentación oficial](https://laravel.com/docs/13.x/upgrade)
- [laravel/framework, rama master en GitHub](https://github.com/laravel/framework/tree/master)
- [composer.json de la rama master](https://github.com/laravel/framework/blob/master/composer.json)
- [What's coming in Laravel 14, Laravel News](https://laravel-news.com/laravel-14)
- [Laravel Shift](https://laravelshift.com/)

---

## Sitemap

Índice completo del sitio: [/sitemap.md](https://www.angelcruz.dev/sitemap.md)

Canónico HTML: [https://www.angelcruz.dev/post/laravel-novedades](https://www.angelcruz.dev/post/laravel-novedades)
