> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Guía de actualización de Laravel 11 a 12

> Se explican los pasos de actualización de Laravel 11 a 12 y los principales cambios.

## Introducción

Laravel 12 se lanzó en febrero de 2025. Esta guía explica los pasos para actualizar de Laravel 11.x a 12.x.

<Info>
  El tiempo estimado necesario para la actualización es de **unos 5 minutos**. Sin embargo, el impacto de los cambios disruptivos en tu aplicación varía según el tamaño y las funcionalidades utilizadas.
</Info>

### Actualización automatizada con Laravel Shift

Puedes automatizar la actualización con [Laravel Shift](https://laravelshift.com/). Shift actualiza automáticamente las dependencias y los archivos de configuración de tu aplicación.

***

## Cambios por nivel de impacto

### Impacto: alto

* Actualización de dependencias
* Actualización del instalador de Laravel

### Impacto: medio

* Trait `HasUuids` de Eloquent y UUIDv7

### Impacto: bajo

* Carbon 3
* Mapeo por índice de resultados en Concurrency
* Resolución de dependencias de clase en el contenedor
* Exclusión de SVG en la validación de imagen
* Ruta raíz por defecto del disco de sistema de archivos local
* Inspección de base de datos con múltiples schemas
* Merge de peticiones con arrays anidados

***

## Pasos de actualización

### Actualización de dependencias

**Impacto: alto**

Actualiza las siguientes dependencias en `composer.json`.

```json theme={null}
{
  "require": {
    "laravel/framework": "^12.0"
  },
  "require-dev": {
    "phpunit/phpunit": "^11.0",
    "pestphp/pest": "^3.0"
  }
}
```

Después, instala las dependencias con el siguiente comando.

```shell theme={null}
composer update
```

***

### Actualización del instalador de Laravel

**Impacto: alto**

Si creas nuevas aplicaciones de Laravel con el CLI del instalador, actualízalo a la versión compatible con Laravel 12.x y con los [nuevos starter kits](https://laravel.com/starter-kits).

Si lo instalaste con `composer global require`:

```shell theme={null}
composer global update laravel/installer
```

Si lo instalaste con `php.new`, ejecuta el comando de reinstalación según tu SO.

<Tabs>
  <Tab title="macOS">
    ```shell theme={null}
    /bin/bash -c "$(curl -fsSL https://php.new/install/mac/8.4)"
    ```
  </Tab>

  <Tab title="Windows PowerShell">
    ```shell theme={null}
    # Ejecutar como administrador
    Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://php.new/install/windows/8.4'))
    ```
  </Tab>

  <Tab title="Linux">
    ```shell theme={null}
    /bin/bash -c "$(curl -fsSL https://php.new/install/linux/8.4)"
    ```
  </Tab>
</Tabs>

Si usas la versión bundled de [Laravel Herd](https://herd.laravel.com), actualiza el propio Herd a la última release.

***

## Nuevos starter kits

En Laravel 12 se han introducido nuevos starter kits que sustituyen a Breeze y Jetstream. Al ejecutar `laravel new` puedes elegir de forma interactiva el stack de frontend.

Starter kits disponibles:

* **React**: Inertia 2, React 19, TypeScript, Tailwind 4, shadcn/ui
* **Vue**: Inertia 2, Vue Composition API, TypeScript, Tailwind 4, shadcn-vue
* **Svelte**: Inertia 2, Svelte 5, TypeScript, Tailwind 4, shadcn-svelte
* **Livewire**: Livewire, Tailwind 4, Flux UI

```shell theme={null}
laravel new my-app
```

Al ejecutar el comando se te pide elegir un starter kit. Tras seleccionarlo, basta con instalar las dependencias y arrancar el servidor de desarrollo.

```shell theme={null}
cd my-app
npm install && npm run build
composer run dev
```

<Info>
  Si estás actualizando una aplicación existente, no hace falta reintroducir el starter kit. Es un cambio para proyectos nuevos.
</Info>

***

## Cambios disruptivos (Breaking Changes)

### Eloquent

#### Trait `HasUuids` y UUIDv7

**Impacto: medio**

El trait `HasUuids` ahora devuelve UUID v7 (UUID ordenables). Si quieres mantener el comportamiento anterior de UUID v4 ordenables, cambia al trait `HasVersion4Uuids`.

```php theme={null}
use Illuminate\Database\Eloquent\Concerns\HasUuids; // [tl! remove]
use Illuminate\Database\Eloquent\Concerns\HasVersion4Uuids as HasUuids; // [tl! add]
```

Si venías usando el trait `HasVersion7Uuids`, cámbialo al trait `HasUuids` (ahora tiene el mismo comportamiento).

***

### Validación

#### Exclusión de SVG en la validación de imagen

**Impacto: bajo**

La regla de validación `image` ya no permite SVG por defecto. Si quieres permitir SVG, indícalo explícitamente.

```php theme={null}
use Illuminate\Validation\Rules\File;

'photo' => 'required|image:allow_svg'

// o bien
'photo' => ['required', File::image(allowSvg: true)],
```

***

### Storage

#### Ruta raíz por defecto del disco de sistema de archivos local

**Impacto: bajo**

Si no defines explícitamente el disco `local` en la configuración de `filesystems`, la ruta raíz por defecto ha cambiado de `storage/app` a `storage/app/private`.

Para mantener el comportamiento anterior, define el disco `local` explícitamente en el archivo de configuración.

```php theme={null}
// config/filesystems.php
'local' => [
    'driver' => 'local',
    'root' => storage_path('app'),
],
```

***

### Base de datos

#### Inspección de base de datos con múltiples schemas

**Impacto: bajo**

`Schema::getTables()`, `Schema::getViews()` y `Schema::getTypes()` devuelven ahora por defecto los resultados de todos los schemas. Para acotar a un schema concreto, pasa el argumento `schema`.

```php theme={null}
// Tablas de todos los schemas
$tables = Schema::getTables();

// Solo tablas del schema 'main'
$tables = Schema::getTables(schema: 'main');
```

`Schema::getTableListing()` devuelve ahora por defecto los nombres de tabla calificados con el schema.

```php theme={null}
$tables = Schema::getTableListing();
// ['main.migrations', 'main.users', 'blog.posts']

$tables = Schema::getTableListing(schema: 'main', schemaQualified: false);
// ['migrations', 'users']
```

#### Cambios en la firma del constructor de Database

**Impacto: muy bajo**

Los constructores de `Illuminate\Database\Schema\Blueprint` e `Illuminate\Database\Grammar` requieren ahora una instancia de `Connection` como primer argumento.

```php theme={null}
// Laravel <= 11.x
$grammar = new MySqlGrammar;
$grammar->setConnection($connection);

// Laravel >= 12.x
$grammar = new MySqlGrammar($connection);
```

Además, se han eliminado o marcado como obsoletas las siguientes APIs.

| API                                              | Estado    |
| ------------------------------------------------ | --------- |
| `Blueprint::getPrefix()`                         | Obsoleta  |
| `Connection::withTablePrefix()`                  | Eliminada |
| `Grammar::getTablePrefix()` / `setTablePrefix()` | Obsoletas |
| `Grammar::setConnection()`                       | Eliminada |

Obtén el prefijo de tabla directamente desde la conexión.

```php theme={null}
$prefix = $connection->getTablePrefix();
```

***

### Concurrency

#### Mapeo por índice de resultados

**Impacto: bajo**

Al pasar un array asociativo a `Concurrency::run()`, los resultados se devuelven ahora con la clave correspondiente.

```php theme={null}
$result = Concurrency::run([
    'task-1' => fn () => 1 + 1,
    'task-2' => fn () => 2 + 2,
]);

// ['task-1' => 2, 'task-2' => 4]
```

***

### Contenedor

#### Valor por defecto en la resolución de dependencias de clase

**Impacto: bajo**

El contenedor de DI ahora respeta los valores por defecto de las propiedades de clase al resolver una instancia de clase.

```php theme={null}
class Example
{
    public function __construct(public ?Carbon $date = null) {}
}

$example = resolve(Example::class);

// Laravel <= 11.x: devuelve una instancia de Carbon
// Laravel >= 12.x: devuelve null
```

***

### Request

#### Merge de peticiones con arrays anidados

**Impacto: bajo**

Ahora puedes hacer merge con `$request->mergeIfMissing()` de datos de array anidados usando notación por puntos. Antes, las claves con notación por puntos se creaban tal cual como claves de nivel superior.

```php theme={null}
$request->mergeIfMissing([
    'user.last_name' => 'Otwell',
]);
```

***

### Enrutamiento

#### Prioridad de rutas

**Impacto: bajo**

Se ha unificado el comportamiento con y sin caché cuando hay varias rutas con el mismo nombre. Incluso sin caché de rutas, ahora tiene prioridad la ruta registrada primero, no la última.

***

### Autenticación

#### Cambios en el constructor de `DatabaseTokenRepository`

**Impacto: muy bajo**

El constructor de `Illuminate\Auth\Passwords\DatabaseTokenRepository` recibe ahora el parámetro `$expires` en segundos en lugar de en minutos.

***

### Carbon 3

**Impacto: bajo**

Se ha eliminado el soporte de Carbon 2.x. Todas las aplicaciones de Laravel 12 requieren [Carbon 3.x](https://carbon.nesbot.com/guide/getting-started/migration.html).

***

## Conclusión

Laravel 12 es una versión que se puede actualizar de forma relativamente fluida. Resumen de los principales puntos a tener en cuenta.

| Cambio                                             | Impacto | Acción                                                  |
| -------------------------------------------------- | ------- | ------------------------------------------------------- |
| Actualización de dependencias en `composer.json`   | Alto    | Cambiar a `laravel/framework ^12.0`                     |
| Actualización del instalador de Laravel            | Alto    | `composer global update`                                |
| `HasUuids` → UUIDv7                                | Medio   | Si es necesario, cambiar a `HasVersion4Uuids`           |
| Exclusión de SVG en la validación `image`          | Bajo    | Añadir `allow_svg` si quieres permitir SVG              |
| Cambio de la ruta raíz por defecto del disco local | Bajo    | Indicarla explícitamente en el archivo de configuración |
| Carbon 3 obligatorio                               | Bajo    | Comprobar la compatibilidad de la API                   |

***

## Referencias

* [Guía oficial de actualización (inglés)](https://laravel.com/docs/12.x/upgrade)
* [Diff del repositorio laravel/laravel (11.x → 12.x)](https://github.com/laravel/laravel/compare/11.x...12.x)
* [Nuevos starter kits](https://laravel.com/starter-kits)
* [Laravel Shift](https://laravelshift.com): servicio comunitario que automatiza la actualización
* [Guía de migración de Carbon 3](https://carbon.nesbot.com/guide/getting-started/migration.html)


## Related topics

- [Guía de actualización de Laravel 12 a 13](/es/blog/upgrade-12-to-13.md)
- [Actualización de Laravel 10 a 11](/es/blog/upgrade-10-to-11.md)
- [Actualización de Laravel 8 a 9](/es/blog/upgrade-8-to-9.md)
- [Actualización de Laravel 9 a 10](/es/blog/upgrade-9-to-10.md)
- [Resumen de las novedades de Laravel 13](/es/blog/laravel-13-new-features.md)
