Ofertas de Fin de Verano

Todos los planes rebajados hasta el 31 de agosto.

Ver planes
00 Días
00 Horas
00 Minutos
00 Segundos

Ofertas de Fin de Verano

Precios rebajados en todos los planes, para nuevas suscripciones y renovaciones. Solo hasta el 31 de agosto.
Ver planes
Saltar al contenido

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 bin global de Composer en tu PATH.

  • 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/lsp

Con 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.

school Curso completo

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.

access_time 8 horas de contenido
layers 4 tecnologías en 1
update 100% actualizado
code Proyectos prácticos
Ver Curso Laravel 12 arrow_forward

star Incluido en cualquier suscripción

Rutas de aprendizaje