Open-source project
SmiteshP/nvim-navic avatar
SmiteshP/nvim-navic

nvim-navic for LSP-aware context in Neovim

Simple winbar/statusline plugin that shows your current code context

1,684 stars63 forksLuaApache-2.0

At a glance

What is it?
nvim-navic is a Lua statusline and winbar component that displays the current code context supplied by a Language Server Protocol client. It fits Neovim users who already configure LSP, but its one-server-per-buffer rule and dependency on document symbols require careful integration.
Who is it for?
Adopt nvim-navic if your Neovim configuration already has an LSP server that provides document symbols and you want a compact, clickable code-context indicator. Do not adopt it as a standalone navigation tree, for buffers without document symbols, or for workflows that require multiple LSP servers to drive one context display.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 51 days ago.
What is it written in?
Mainly Lua, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Why nvim-navic belongs in an LSP-enabled Neovim setup

nvim-navic addresses a narrow gap in Neovim: showing where the cursor sits inside a source file without occupying an entire screen with a navigation tree. Its purpose is to turn LSP document symbols into a short context trail suitable for a statusline or winbar. The intended user is already running Neovim 0.7.0 or newer and has neovim/nvim-lspconfig in the editor configuration. A language server must attach to the buffer before nvim-navic can build that display.

This makes nvim-navic a presentation component rather than a replacement for an LSP client or language server. It does not parse source files independently and does not create an index of project definitions. Instead, it depends on the symbol information exposed by the attached server. That boundary matters for adoption. A buffer may have syntax highlighting without having an active language server, and a language server may be attached without advertising documentSymbolProvider. In either case, nvim-navic has no documented fallback parser.

The plugin also supports click interaction. With that option enabled, a single click can move to a displayed element, while a double click can open nvim-navbuddy for the clicked element. This creates a useful distinction between passive context and active navigation, although click navigation is disabled by default. Users who only need a visual location indicator can leave the interaction out of their configuration.

How document symbols become statusline context

The data flow begins with an LSP client attaching to a buffer. nvim-navic's attach function receives the client and buffer number, then requests or consumes document-symbol information for that buffer. As the cursor moves, the plugin selects the symbols applicable to the current position and formats the resulting hierarchy into display segments. The README identifies CursorMoved as the event that normally triggers context updates.

Each segment can receive an icon chosen from a table of symbol kinds. The setup options distinguish files, modules, namespaces, packages, classes, methods, properties, functions, variables, constants, strings, numbers, arrays, objects, and other document-symbol categories. A format_text function can transform the text of each segment. Separator controls what appears between entries, while depth_limit limits how much of the hierarchy is rendered. When the configured depth is reached, depth_limit_indicator marks the truncation.

Highlight support is optional. If highlight is true, the display can use NavicIcons*, NavicText, and NavicSeparator groups. Default icons assume that a Nerd Font is available, so a user who does not want icon fonts can set icons.enabled to false. The safe_output option sanitizes rendered content for statusline and winbar use. These details show that nvim-navic owns formatting and presentation after receiving symbol data, while ownership of parsing remains with the language server.

Installing nvim-navic with packer or vim-plug

The README lists Neovim 0.7.0 or newer and neovim/nvim-lspconfig as requirements. With packer, the dependency is declared in the plugin specification. The repository and dependency names must remain exactly as shown because package managers resolve them directly.

The packer specification adds nvim-navic and declares its nvim-lspconfig requirement:

lua
use {
    "SmiteshP/nvim-navic",
    requires = "neovim/nvim-lspconfig"
}

For vim-plug, declare nvim-lspconfig first and nvim-navic second. After the package manager loads the plugin, the next required step is attaching it to an LSP client:

vim
Plug "neovim/nvim-lspconfig"
Plug "SmiteshP/nvim-navic"

The README does not document a standalone startup command for nvim-navic. It is a Lua module loaded through require("nvim-navic"), and its useful output depends on an active LSP attachment. Installation alone therefore does not add context to the statusline. The user must also integrate nvim-navic with the statusline or winbar component and enable at least one server that can supply document symbols.

Attaching the plugin to a document-symbol server

The README's first setup example uses clangd. The navic.attach callback receives the LSP client and buffer number from on_attach, so the plugin follows the attachment lifecycle rather than trying to discover an arbitrary server itself.

A minimal documented clangd configuration is:

lua
local navic = require("nvim-navic")

vim.lsp.config('clangd', {
    on_attach = function(client, bufnr)
        navic.attach(client, bufnr)
    end
})

vim.lsp.enable('clangd')

After Neovim attaches clangd and opens a buffer covered by that server, the plugin can obtain document symbols and expose the relevant context for statusline rendering. If nvim-lspconfig's auto_attach option has already enabled attachment, the README says the explicit navic.attach step can be skipped.

The more careful integration guards attachment with client.server_capabilities.documentSymbolProvider. This avoids sending unsupported clients into a path the plugin expects to provide symbols:

lua
local navic = require("nvim-navic")

local on_attach = function(client, bufnr)
    if client.server_capabilities.documentSymbolProvider then
        navic.attach(client, bufnr)
    end
end

vim.lsp.config('clangd', {
    on_attach = on_attach
})

vim.lsp.enable('clangd')

The omitted ellipsis in the README represents any other shared on_attach work. It is not necessary to reproduce that placeholder. The important part is the capability check, which directly addresses the server requirement documented by the project.

Choosing one LSP server and controlling update frequency

nvim-navic can attach to only one server per buffer, according to the README. This is the clearest deployment constraint. A configuration that starts several language servers for overlapping file types must decide which one supplies the context rather than expecting every attachment to coexist in the same buffer.

The lsp.preference option ranks server names. A lower index has higher priority. The README gives clangd and pyright as an illustrative preference list, even though they normally concern different ecosystems, because the actual ordering applies to whatever servers overlap a given buffer. Automatic attachment is available through lsp.auto_attach and is disabled by default.

Cursor movement can also create update pressure in large files. The buffer-local option vim.b.navic_lazy_update_context postpones updates away from every CursorMoved event for that buffer. The documentation points to its usage notes for details. A global setup can use lazy_update_context = true to disable CursorMoved-based updates for all buffers, leaving context refreshes to occur on CursorHold events. This is a direct trade-off between fresher movement updates and fewer updates in large documents.

The README also discusses vim.g.navic_silence. Suppressing errors can hide messages, but the project explicitly warns that those errors identify unsupported documentSymbol servers or multiple server attachments. Disabling diagnostics makes a misconfiguration less visible without correcting it.

nvim-navic compared with nvim-navbuddy navigation

nvim-navbuddy is the closest project-specific companion named in the README, but it should not be described as a drop-in replacement. The README calls the pairing a complete breadcrumbs experience like an IDE, while nvim-navic itself is described as a simple statusline or winbar component. In other words, their roles differ. nvim-navic renders current context and can navigate to a clicked element. nvim-navbuddy provides the companion interaction that nvim-navic can open on a double click.

The architecture also explains why the pair is optional. nvim-navbuddy is not a required dependency in either installation example, and nvim-navic can run without click handling. Users who want a compact context trail for the winbar can use nvim-navic alone. Users who want the documented double-click path into a fuller breadcrumb interface need both projects. Enabling click behavior without nvim-navbuddy available would not satisfy that advertised double-click workflow.

For customization, nvim-navic changes the rendered symbols, icons, separators, depth, highlights, safety handling, update schedule, server preference, and click behavior. Those controls affect a small contextual display. They do not turn the plugin into a document outline interface. That makes it easier to judge whether its output fits an existing Neovim statusline rather than adding another large panel to the editing window.

Maintenance, releases, and the Apache-2.0 boundary

The repository is not archived, and its last push was on 2026-09-02. It has no GitHub releases, so there is no documented release-number or upgrade-track convention in the documented repository information. Version pinning through a particular package manager is not shown either. Maintenance and upgrade planning therefore has to account for configuration compatibility rather than a published release cadence.

The documented Neovim floor is version 0.7.0. The setup examples use the newer vim.lsp.config and vim.lsp.enable calls, while the requirements still state nvim-lspconfig. This combination indicates that users should compare the example against their own Neovim and nvim-lspconfig configuration rather than copying it mechanically across editor versions.

The project uses the Apache-2.0 license. That identifier identifies the license recorded for the repository, but this review does not interpret its legal obligations. An adopter distributing the plugin or incorporating parts of it should read LICENSE.md and assess the actual use case. There is no separate documentation here about telemetry, external services, generated files, or a compatibility policy, so those points cannot be inferred from the repository layout.

Editorial conclusion

Adopt nvim-navic if your Neovim configuration already has an LSP server that provides document symbols and you want a compact, clickable code-context indicator. Do not adopt it as a standalone navigation tree, for buffers without document symbols, or for workflows that require multiple LSP servers to drive one context display. Before adding it to a full setup, verify documentSymbolProvider support, choose the preferred server through navic.setup, and check how context updates behave in large files.

Frequently asked questions

What are the requirements for installing nvim-navic?

The README requires Neovim 0.7.0 or newer and neovim/nvim-lspconfig. The plugin also needs to attach to a language server that provides document symbols.

How do I attach nvim-navic to an LSP client?

Load it with require("nvim-navic"), then call navic.attach(client, bufnr) from the server's on_attach callback. The README also allows skipping this when LSP auto_attach is enabled.

Can nvim-navic use multiple LSP servers for one buffer?

No. The README states that nvim-navic can attach to only one server per buffer. The lsp.preference setup option determines which attached server has priority when several are present.

How can I reduce nvim-navic updates in large files?

Set vim.b.navic_lazy_update_context = true for a specific buffer, or enable lazy_update_context in navic.setup to disable CursorMoved-based context updates globally. The documentation says context can then update on CursorHold events.

Does nvim-navic require Nerd Fonts?

Not strictly. Its default icons assume a Nerd Font, but setting icons.enabled = false hides all icons.

Official sources

  1. Issues
  2. License: Apache-2.0
  3. README
  4. SmiteshP/nvim-navic on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/smiteshp-nvim-navic.svg)](https://hysenlabs.com/projects/smiteshp-nvim-navic)

Was this useful?