Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Lsp Laravel Package

laravel/lsp

Laravel LSP adds framework-aware editor support for Laravel and Blade, with completions, hovers, diagnostics, document links, Go to Definition, and code actions across routes, views, translations, config, and env vars. Install globally via Composer and launch over stdio from your project root.

View on GitHub
Deep Wiki
Context7

Getting Started

Laravel LSP is a dev-only, global tool. It never enters a project's composer.json, so it never ships to production or shows up in a lockfile review.

  1. Install the binary once per machine.

    composer global require laravel/lsp
    

    Confirm Composer's global bin directory is on PATH. This is the single most common first failure — the install succeeds, then the editor reports "command not found". Verify in a fresh shell that laravel-lsp resolves. Don't run it manually: it speaks JSON-RPC over stdio and will just sit there waiting for a frame.

  2. Install the editor client. Official extensions exist for VS Code, Cursor (same extension), Sublime Text, and Zed; they launch the server with no manual config. Neovim (0.11+) and OpenCode need a small config block from the README. The extensions are thin launchers — all the intelligence is in the global binary.

  3. Open the Laravel project root, not a parent directory. The server locates the application by finding artisan. Open a monorepo root, a Docker mount root, or your home directory and you either get no attach at all (Neovim's root_dir callback refuses without artisan) or an index built against the wrong tree.

  4. Smoke-test the five jumps. The whole value proposition is Laravel hiding structure inside strings. Open a controller and try, in order:

    • view('dashboard.index') → Go to Definition lands on the Blade file.
    • route('users.show', $user) → hover shows verb and URI; definition jumps to the route registration.
    • config('services.stripe.key') → definition into config/services.php.
    • __('auth.failed') → definition into the matching locale file.
    • env('DB_HOST') → definition into .env.

    If those five resolve, the install is healthy. Blade navigation is the differentiator versus generic PHP tooling; test it early, because it is the reason to run this alongside Intelephense rather than instead of it.

  5. Confirm diagnostics fire. Write view('does.not.exist') and wait. Indexing happens on initialized, so the first document of a session may lag; subsequent edits are incremental.

Where to look first in the docs: the two configuration tables in the README — server options (phpEnvironment, phpCommand, definitionProvider, Pest options) and the per-feature boolean matrix. Together they're the entire operational surface area of the package. The Neovim snippet is also worth reading even if you never use Neovim — it's the clearest statement of the root-detection contract.

Implementation Patterns

Write an onboarding doc per repo, not a mandated editor. Editor diversity is the point of this package; forcing everyone onto VS Code to get framework awareness throws away the advantage. Keep a docs/editor.md in each Laravel app with the global install line, the config block for the two or three editors the team actually uses, and a restart instruction — that's the step everyone forgets.

Reproduce the artisan gate in whatever client you use. It's what stops the server launching for every non-Laravel PHP project you ever open:

vim.lsp.config("laravel_lsp", {
    cmd = { "laravel-lsp" },
    filetypes = { "php", "blade" },
    root_dir = function(bufnr, on_dir)
        local root = vim.fs.root(bufnr, "artisan")
        if root then on_dir(root) end
    end,
})
vim.lsp.enable("laravel_lsp")

Pin the PHP runtime when local php isn't the app's PHP. phpEnvironment defaults to auto, which tries Herd → Valet → Sail → Lando → DDEV → local PHP and silently falls back to bare php if nothing is detected. On Sail or Lando projects, be explicit:

{ "phpCommand": ["./vendor/bin/sail", "php"] }

phpCommand always wins over phpEnvironment. This matters most in containers, remote workspaces, and CI-like environments where the editor's shell isn't the app's shell — a wrong PHP binary means an empty index and therefore empty completions, with no visible error.

Tune the feature matrix per project. Every feature flag defaults to true. On an Inertia app, Mix flags are dead weight; on a Livewire app, Inertia flags are. Turn domains off rather than tolerate noise, since diagnostics you don't care about train people to ignore diagnostics you do:

{
  "mixCompletion": false,
  "mixDiagnostics": false,
  "mixHover": false,
  "mixLink": false,
  "inertiaCompletion": true,
  "inertiaDiagnostics": true
}

Use diagnostics as a string-reference engine during refactors. The highest-leverage daily workflow isn't completion, it's deletion. Rename a Blade view, move a config key, drop an env var, retire a translation key — then read the diagnostics across the codebase to find every view(), config(), env(), and __() call still pointing at the old name. This is the "grep for Laravel's indirection" you can't get from rg, because the references are strings rather than symbols.

Lean on document links for review and onboarding. Hover-then-follow on routes, views, middleware, policies, container bindings, and path helpers turns review into navigation. New hires get a fast mental map of a mature app without asking where HandleInertiaRequests or a policy actually lives.

Decide what to do with Pest docblocks deliberately. pestGenerateDocBlocks defaults to true and writes to storage/framework/testing/_pest.php. That path is inside storage/framework, which is normally gitignored — so the file regenerates per machine, which is usually what you want. It refreshes when tests or Composer autoload files change; if helper docblocks look stale after adding a test file, that regeneration is the mechanism to check first.

Run it next to a type-aware PHP server, not instead of one. This package supplies framework awareness (routes, views, translations, config, env, middleware, policies, bindings, validation rules, controller actions, Eloquent, Blade). It is not a general PHP type-inference engine. Attach both for php filetypes; they answer different questions.

Treat the binary like a toolchain dependency. It's global, so versions drift across the team. Document an update command and bump it in lockstep with editor extensions — features and initializationOptions keys are still moving quickly, and a stale binary against a newer extension is a confusing failure mode.

Gotchas and Tips

  • command not found is a PATH problem, not an install problem. Fix the shell profile, then restart the editor, not just the terminal — GUI editors don't inherit a freshly edited profile.
  • Never invoke laravel-lsp interactively. It blocks on stdio awaiting JSON-RPC. If it "hangs," that's correct behavior.
  • No artisan, no attach. Remote containers, devcontainers, and monorepos are the usual offenders. Open the directory containing artisan, or set an explicit phpCommand for the container.
  • Unknown phpEnvironment values fail silently to plain php. Typo "sail" as "sails" and you get a working-looking server with an empty index rather than an error.
  • Sail/Lando/DDEV detection requires the environment to be running. Start Sail before opening the project, or set phpCommand explicitly and skip detection entirely.
  • definitionProvider: false disables all Go to Definition. More subtly, definitions are resolved from enabled document link options — so turning off configLink also removes config go-to-definition even though definitionProvider is still true. Disable a link flag only if you're happy losing navigation for that domain.
  • First open of a large app is slow. Indexing runs on initialized; empty or partial completions for the first few seconds are normal. Don't "fix" it by restarting repeatedly.
  • Stale index after out-of-editor changes. File watchers invalidate providers on watched-file changes, but scaffolding generated by artisan make:* while the server is idle, or edits made by a second tool, can leave route/view/translation data behind. Restart the server after bulk generation or a composer install.
  • Windows uses the sequential StdioTransport rather than the concurrent Amp transport, so expect lower throughput on very large repositories. Not a defect — just plan for it.
  • Neovim needs 0.11+ and correct filetypes. If Blade completions never appear, check that .blade.php buffers actually report blade, not php or html. OpenCode's custom-server config, by contrast, keys off the literal extension ".blade.php".
  • Platform support is narrow: macOS arm64/x64, Linux arm64/x64, Windows x64. Unsupported architectures get no binary — verify before troubleshooting config.
  • Debug in the editor's LSP log, not the app's log. Completions that return nothing almost always trace back to a bad PHP command, a wrong root, or a feature flag that's off — not to a bug in the server.
  • Documentation is README-first. There's no deep prose guide; the configuration tables are the reference. When something is ambiguous, read the flags rather than guessing, and prefer the official editor extensions over hand-rolled config.
  • Extension points (if you go past usage): the server is a Laravel Zero CLI with a FeatureRegistry building per-capability providers against contracts like CompletionProvider, HoverProvider, DiagnosticProvider, and LinkProvider; project facts come from DataProvider implementations managed by ProjectIndex, with invalidation driven by watchers under app/Lsp/Watchers/. Adding a domain means a data provider plus one thin provider per capability — a good first contribution, and the reason feature coverage keeps expanding.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
vento/laravel-airbrake
wfeller/laravel-batch
maco-studios/mage-os-installer
busarm/armie
siberfx/laravel-logger
kfteam1991/dcat-admin
dashed/dashed-laposta
dashed/dashed-ecommerce-montaportal
dashed/dashed-ecommerce-etsy
neohq/string-blade-compiler
log1x/acf-composer
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent
sierratecnologia/media-manager