SOLVED: Vue LSP Attaches but No Features Working (Tried Everything)

Hi everyone,

I’m having a persistent issue getting the Vue language server to work correctly in Neovim and I’m hoping someone can spot what I’m missing.

The Problem:

When I open a .vue file, :LspInfo shows that both vue_ls and ts_ls are attached to the buffer, which seems correct for the recommended “Hybrid Mode” setup. However, I get absolutely no LSP functionality—no completion, no hover/documentation, no go-to-definition, etc. My keymaps work fine for other language servers like astro and tsserver in .ts files, so the issue is specific to the Vue setup.

What I’ve Tried:

I feel like I’ve tried every possible configuration, including:

  • “Hybrid Mode” (current attempt): Using vue_ls alongside ts_ls with the @vue/typescript-plugin .

  • “No Hybrid Mode”: Using vue_ls alone with hybridMode = false and pointing it to the correct tsdk path.

  • **vtsls with nvim-vtsls

  • Reinstalling packages: Ensuring @vue/language-server and @vue/typescript-plugin have matching versions by reinstalling them globally with npm .

  • Checking for conflicts: Temporarily disabling other servers like eslint and biome for .vue files.

No matter what I try, the result is the same: the servers attach, but no features work.

My Current Configuration:

Here is the “Hybrid Mode” setup I’m currently trying, which follows the nvim-lspconfig documentation:

-- In my lsp config file:

-- TypeScript Server with Vue Plugin
vim.lsp.config("ts_ls", {
        filetypes = {
          "javascript",
          "javascriptreact",
          "javascript.jsx",
          "typescript",
          "typescriptreact",
          "typescript.tsx",
          "vue",
        },
        init_options = {
          plugins = {
            {
              name = "@vue/typescript-plugin",
              location = os.getenv("HOME") .. "/.local/share/nvm/v24.1.0/lib/node_modules/@vue/typescript-plugin",
              languages = { "vue" },
            },
          },
        },
        cmd = { "typescript-language-server", "--stdio" },
        capabilities = capabilities,
      })
vim.lsp.enable("ts_ls")

-- Vue Server for HTML/CSS
vim.lsp.config("vue_ls", {
    capabilities = capabilities,
})
vim.lsp.enable("vue_ls")

:LspInfo Output (in a .vue file):

vim.lsp: Active Clients ~
- emmet_ls (id: 1)
  - Version: ? (no serverInfo.version response)
  - Root directory: nil
  - Command: { "emmet-ls", "--stdio" }
  - Settings: {}
  - Attached buffers: 3
- ts_ls (id: 2)
  - Version: ? (no serverInfo.version response)
  - Root directory: ~/Downloads/test-vue
  - Command: { "typescript-language-server", "--stdio" }
  - Settings: {}
  - Attached buffers: 3
- vue_ls (id: 3)
  - Version: ? (no serverInfo.version response)
  - Root directory: ~/Downloads/test-vue
  - Command: { "vue-language-server", "--stdio" }
  - Settings: {}
  - Attached buffers: 3

My Full Config:

You can find my full Neovim configuration here: [GitHub - bushblade/nvim: My Neovim Config - currently using Version 0.11.2]

I’m at a complete loss. Any ideas on what could be causing this or what I should check next would be massively appreciated.

Thanks in advance!

I have discovered that if I disable vue_ls entirely, just commenting it out:

      -- Vue JS
      -- vim.lsp.config("vue_ls", {
      --   filetypes = { "vue" }, -- Only attach to .vue files
      --   capabilities = capabilities,
      -- })
      -- vim.lsp.enable("vue_ls")

Then TS language server features are now available in .vue files.

Just following up for anyone else that may run into this.
I finally got it working following this guide to use vtsls instead of ts_ls.