Taylor Otwell presentó Laravel LSP en el primer día de Laracon US 2026. Es un language server de primera parte: un proceso independiente que indexa tu aplicación y le explica al editor cosas que el editor no puede saber por sí mismo, como qué claves de configuración existen, qué rutas tienen nombre o a qué archivo apunta una vista.
Hasta ahora Laravel mantenía una extensión oficial solo para VS Code. Si trabajabas en Zed, Sublime Text o Neovim dependías de proyectos de la comunidad, con la calidad y el mantenimiento que cada uno tuviera. Laravel LSP saca esa funcionalidad a un servidor que habla el protocolo LSP por stdio, así que cualquier editor con un cliente LSP puede usarlo.
Requisitos
PHP 8.2 o superior.
El directorio
binglobal de Composer en tuPATH.Un editor con soporte LSP.
El paquete distribuye binarios precompilados para macOS (arm64 y x64), Linux (arm64 y x64) y Windows (x64).
Instalación
composer global require laravel/lspCon eso tienes el ejecutable laravel-lsp disponible. El servidor se comunica por entrada y salida estándar, y conviene arrancarlo desde la raíz del proyecto Laravel para que la indexación encuentre todo.
Si vas a usarlo en Zed, Sublime Text, VS Code o Cursor, este paso te lo puedes saltar: la extensión oficial de cada editor descarga el binario por su cuenta. La instalación con Composer es para Neovim, OpenCode o cualquier otro cliente LSP que configures a mano.
Qué conoce de tu aplicación
El servidor indexa el proyecto y responde a las peticiones del editor contra ese índice. La cobertura abarca casi todas las zonas del framework que se manejan con strings:
Área | Capacidades |
|---|---|
Rutas | Completado, hover, diagnósticos, enlaces |
Vistas y Blade | Completado, hover, diagnósticos, enlaces, correcciones |
Traducciones | Completado de clave, locale y parámetros; hover |
Configuración | Completado de claves, hover, diagnósticos, enlaces |
Variables de entorno | Completado, hover, diagnósticos, enlaces, correcciones |
Assets y Mix | Completado, hover, diagnósticos, enlaces |
Middleware | Completado, hover, diagnósticos, enlaces |
Inertia | Completado de páginas y props, enlaces, diagnósticos |
Componentes Livewire | Completado, hover, enlaces |
Auth y policies | Completado, hover, diagnósticos, enlaces |
Bindings del contenedor | Completado, hover, diagnósticos, enlaces |
Reglas de validación | Completado |
Acciones de controlador | Completado, diagnósticos, enlaces |
Eloquent | Completado |
En la demo, escribir config('app.time dentro de un controlador desplegaba la lista de claves que coinciden con su valor resuelto al lado: app.timezone mostrando UTC. Una clave inexistente aparece como diagnóstico, igual que un error de sintaxis.
Los document links son la parte que más se nota en el día a día. Convierten view('orders.index') y route('orders.show') en enlaces sobre los que se puede hacer clic, y esos mismos datos alimentan el "ir a definición", que viene activado por defecto.
Configuración por editor
Sublime Text, Zed y VS Code tienen extensión oficial de Laravel que se encarga del cableado. Cursor funciona con la extensión de VS Code. Neovim y OpenCode necesitan un poco de configuración a mano.
Cómo queda en Zed
Este es el editor con el que trabajo, así que voy con el proceso completo. Si todavía no lo usas, en Zed: el editor que nos merecemos tienes el setup entero, incluida la conexión con WSL y la configuración de PHP con Sail.
Antes de tocar nada, conviene ver el punto de partida. En un proyecto Laravel sin el LSP, un Gate::authorize('viewAny', Film::class) en un controlador no lleva a ninguna parte: mantienes pulsado Control, pasas por encima y no pasa nada. Lo mismo con una llamada a config(), con un view('films.index') o con el nombre de un middleware en routes/web.php. Todo eso son strings, y para el editor un string es un string.
1. Instalar la extensión oficial
Este es el primer paso, y saltárselo es lo que hace que la configuración parezca rota. En la paleta de comandos, extensions, y busca Laravel. Salen dos: la de la comunidad y la oficial de Laravel. La que hay que instalar es la oficial, que va por la versión 0.1.0. No instales las dos a la vez.
2. Añadir la configuración del proyecto
La documentación de la extensión da este bloque, que va en el settings.json del proyecto y no en el global. Se abre desde la paleta de comandos y Zed crea la carpeta .zed en la raíz del proyecto:
{
"lsp": {
"laravel": {
"initialization_options": {
"phpEnvironment": "sail"
}
}
}
}Ahí va tu entorno de PHP. Con Sail, sail; si prefieres que lo detecte solo, auto.
3. El bloque que falta
Con lo anterior a mí no me arrancaba. Reiniciaba los language servers desde la paleta de comandos, recargaba el workspace, cerraba todos los archivos, y en la lista de servidores activos no aparecía Laravel por ningún lado. Lo que lo arregla es declarar explícitamente qué servidores quieres para PHP:
{
"languages": {
"PHP": {
"language_servers": ["laravel", "intelephense", "!phpactor", "!phptools"]
}
},
"lsp": {
"laravel": {
"initialization_options": {
"phpEnvironment": "sail"
}
}
}
}Los dos importantes son laravel e intelephense, y conviven bien: laravel aporta el conocimiento del framework, e Intelephense sigue haciendo lo suyo con el lenguaje, los tipos y la navegación entre clases. El ! delante de phpactor y phptools los excluye, para no tener varios servidores compitiendo por lo mismo y duplicando sugerencias.
Después de guardar: paleta de comandos, restart language server. Si no ves el cambio, abre un archivo PHP y repítelo, que a veces necesita un buffer del lenguaje abierto para engancharse. En la lista de servidores activos ya debería aparecer Laravel.
4. Comprobar que funciona
Vuelve al controlador. Ahora el string del Gate::authorize() sale subrayado y el clic lleva directamente al método viewAny() de la policy correspondiente. La llamada a config() abre el archivo de configuración, view('films.index') abre la vista, y en routes/web.php el alias de un middleware lleva a su clase.
Ese es el cambio real: dejas de buscar archivos a mano y pasas a navegar por el proyecto igual que navegas entre clases.
Otros editores
Neovim 0.11 o superior:
vim.lsp.config("laravel_lsp", {
cmd = { "laravel-lsp" },
filetypes = { "php", "blade" },
root_markers = { "artisan", "composer.json", ".git" },
})
vim.lsp.enable("laravel_lsp")Y OpenCode, activando LSP en opencode.json:
{
"$schema": "https://opencode.ai/config.json",
"lsp": {
"laravel-lsp": {
"command": ["laravel-lsp"],
"extensions": [".php", ".blade.php"]
}
}
}Qué PHP usa para indexar
El servidor ejecuta scripts contra tu proyecto para construir el índice, así que necesita un comando PHP que funcione. Esto se controla con la opción phpEnvironment, que se pasa dentro del objeto initializationOptions del LSP.
Por defecto vale auto e intenta, en este orden, Herd, Valet, Sail, Lando, DDEV y el PHP local. Puedes fijarlo a uno concreto, como el "phpEnvironment": "sail" del bloque anterior, o saltarte la detección con un phpCommand explícito:
{
"phpCommand": ["./vendor/bin/sail", "php"]
}Si trabajas con Sail merece la pena fijarlo en lugar de dejarlo en auto. Es lo que evita que el servidor indexe con el PHP del host en vez de con el del contenedor, que es donde están las versiones reales de tus dependencias.
Activar y desactivar funcionalidades
Cada capacidad tiene su propio booleano en el mismo objeto de opciones. Se pueden apagar los diagnósticos de rutas con routeDiagnostics y seguir teniendo el completado de rutas, por ejemplo. Es útil cuando una parte del índice da falsos positivos en un proyecto concreto y no quieres renunciar al resto.
Hay dos opciones específicas para Pest. pestGenerateDocBlocks mantiene actualizados los docblocks de los helpers de Pest a medida que cambian los tests y los archivos de autoload, y pestHelperFilePath decide dónde se escribe ese archivo.
Qué cambia en el día a día
Por un lado, los errores que dejas de cometer. Una clave de traducción mal escrita, un config() que apunta a algo que ya no existe, una vista renombrada que dejó atrás tres referencias: todo eso aparecía en runtime y ahora aparece mientras escribes.
Por otro, la navegación. Moverte entre configuración, vistas, policies y middlewares con un clic es de esas cosas que no parecen gran cosa hasta que llevas media hora depurando en un proyecto que no conoces. Y si trabajas en un editor que no es VS Code, es la primera vez que tienes ese nivel de integración con soporte oficial detrás.
La versión de la extensión de Zed es todavía la 0.1.0, así que es esperable encontrarse con detalles como el de la configuración. Aun así, compensa instalarla ya.
Curso Laravel 12
Completo 2026
El único curso 100% actualizado que incluye Laravel 12, Livewire 3, Vue 3, React 19 e Inertia 2. Aprende con proyectos reales y las últimas funcionalidades.
star Incluido en cualquier suscripción