# Migrating from Laravel

The concept map for a Laravel app. The runbook — phases, exit conditions, stop conditions — is
[Migrating an existing app](/migrating-an-existing-app); this page says what each Laravel term
becomes. `As of 2026-11`, against the current release ([laravel.com/docs](https://laravel.com/docs)).

## Concept map

| Laravel | Ultimate |
|---|---|
| `routes/web.php` + a controller that returns a view | a route file: [Routes and render modes](/routes-and-render-modes) |
| a controller that writes, a form request | an `action`, its input schema: [Actions](/actions) |
| an Eloquent model | an `entity()`: [Entities and migrations](/entities-and-migrations) |
| a query scope, the query builder | a `query`: [Queries and live queries](/queries-and-live-queries) |
| `php artisan make:migration`, `migrate` | `x db gen "<name>"`, then `x db migrate` |
| `php artisan make:*` | `x g <kind> <name>` ([CLI reference](/cli-reference)) |
| a queued job | a `job`: [Jobs and workflows](/jobs-and-workflows) |
| the scheduler (`schedule:run`) | a `task`: [Scheduled tasks](/scheduled-tasks) |
| Breeze, Fortify, Sanctum | [Auth](/auth) |
| gates and policies | a `policy`: [Policies and authz](/policies-and-authz) |
| broadcasting (Reverb, Pusher) | a live query: [Realtime](/realtime) |
| Mailables | [Mail](/mail) |
| `Storage` disks | [Storage and uploads](/storage-and-uploads) |
| Nova, Filament | [Admin dashboard](/admin-dashboard) |
| `lang/*.php` | one flat catalog per locale: [I18n](/i18n) |
| Pest, PHPUnit | [Testing](/testing) |
| `php artisan serve` | `x dev` |

## What does not map

| Laravel | Why |
|---|---|
| PHP and its packages | Bun only. A Composer package is rewritten or bought as a service |
| MySQL, SQLite, SQL Server | Postgres only, by design: [Home](/docs) |
| Blade, Livewire | pages render with SolidJS; interactive parts are islands. No converter |
| model events and observers | no implicit hooks: the write is an `action` or a `mutator` that says what it does ([Actions](/actions)) |
| polymorphic relations (`morphTo`) | model each target as its own foreign key ([Entities and migrations](/entities-and-migrations)) |

## Schema adoption

Laravel ids are `bigint` (`$table->id()`) and timestamps are `created_at` / `updated_at`. Phase 1
of the runbook declares the existing tables with the physical-name overrides it gives, then
`x db gen` until `x verify --only drift` agrees: [Migrating an existing app](/migrating-an-existing-app).

## Identity cutover

| Laravel stores | Branch |
|---|---|
| `users.password` as `$2y$…` — bcrypt, Laravel's default driver | **proceed**: verified natively, rewritten as argon2id on first login ([Migrating an existing app](/migrating-an-existing-app)) |
| `$argon2id$…` (the `argon2id` driver) | **proceed**: rehashed when weaker than the policy |
| the session: an encrypted cookie keyed by `APP_KEY` | bridge it with your own verifier behind `configureAuthenticator()`, or keep the Laravel login until every user has signed in once ([Auth](/auth)) |
