Open-source project
hrsh7th/nvim-cmp avatar
hrsh7th/nvim-cmp

hrsh7th/nvim-cmp: a Lua completion engine for Neovim that you wire together yourself

A completion plugin for neovim coded in Lua.

9,486 stars438 forksLuaMIT

At a glance

What is it?
nvim-cmp is a completion engine for Neovim, not a completion source. It ships the popup, the key handling and the LSP capability plumbing, and expects you to install the sources and the snippet engine separately.
Who is it for?
Adopt nvim-cmp if you already run Neovim's built-in LSP client and want to choose each completion source yourself, and you are willing to keep your own keymaps because the cmp.mapping.preset.* tables are documented as changeable without announcement. Do not adopt it if you want one plugin that completes from LSP, buffers and paths out of the box, or if you refuse to configure a snippet engine, since cmp.setup requires the snippet.expand function.
Can I use it commercially?
Yes. MIT 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 82 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 September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What nvim-cmp actually is, and who ends up using it

The README opens with a sentence that defines the project's boundary: it is a completion engine plugin for Neovim written in Lua, and completion sources are installed from external repositories and are "sourced". That single line explains most of the adoption friction. nvim-cmp draws the menu, decides when to trigger, filters and scores candidates, and handles the keys you press while the menu is open. It does not know how to find a variable name in your buffer, a file path on disk, or a method on a language server. Those come from cmp-nvim-lsp, cmp-buffer, cmp-path, cmp-cmdline and similar plugins, each maintained separately.

The audience follows from that split. If you have already configured Neovim's built-in LSP client and you want completion to behave a particular way, nvim-cmp gives you a Lua surface for it. If you want completion to appear after installing one plugin, this is the wrong shape of tool, because a bare install produces no candidates at all. The repository topics list only nvim-cmp, and the README points to a Wiki page titled List of sources for the rest of the ecosystem.

The source pipeline: how candidates reach the menu

Configuration is a single cmp.setup call that takes a table. The sources key is where the pipeline is defined, and the README's example uses cmp.config.sources with two tables. The first table lists sources that are consulted first, in this case nvim_lsp and a snippet source. The second table lists fallback sources, here buffer, which are only consulted when the first group returns nothing. That grouping is the mechanism, not a stylistic choice: it is how you keep a language server's suggestions from being buried under every word in the file.

Each entry is a name string that must match an installed source plugin. The README's example configuration installs cmp-nvim-lsp, cmp-buffer, cmp-path and cmp-cmdline alongside nvim-cmp, which is why the names nvim_lsp, buffer, path and cmdline resolve. The LSP side is connected through a separate step: cmp_nvim_lsp exposes default_capabilities(), and those capabilities are handed to each language server you enable. Without that handoff the server has no reason to send completion items, so the source stays silent.

Command line completion is configured separately from insert mode. The README calls cmp.setup.cmdline twice, once for the search prompts '/' and '?' with the buffer source, and once for ':' with path as the primary source and cmdline as the fallback. The ':' block also sets matching = { disallow_symbol_nonprefix_matching = false }, which the README presents as part of that block rather than as an optional extra.

Installing nvim-cmp and getting a first completion

There is no package on a registry to install. The README's recommended configuration uses vim-plug as the plugin manager, and the project's own repository layout includes an nvim-cmp-scm-1.rockspec, so a LuaRocks path exists, but the README documents the vim-plug route. The block below is the plugin list from that example, trimmed to the LSP and buffer sources plus the vsnip snippet engine.

vim
call plug#begin(s:plug_dir)
Plug 'neovim/nvim-lspconfig'
Plug 'hrsh7th/cmp-nvim-lsp'
Plug 'hrsh7th/cmp-buffer'
Plug 'hrsh7th/cmp-path'
Plug 'hrsh7th/cmp-cmdline'
Plug 'hrsh7th/nvim-cmp'
Plug 'hrsh7th/cmp-vsnip'
Plug 'hrsh7th/vim-vsnip'
call plug#end()

After running :PlugInstall, the Lua configuration goes inside a lua <<EOF heredoc in the same vimrc, or in a file under your Neovim config directory. The snippet engine is required: the README marks the snippet.expand function with REQUIRED, and the vsnip line inside it is the one that matches the plugin list above.

lua
local cmp = require'cmp'
cmp.setup({
  snippet = {
    expand = function(args)
      vim.fn["vsnip#anonymous"](args.body)
    end,
  },
  mapping = cmp.mapping.preset.insert({
    ['<C-Space>'] = cmp.mapping.complete(),
    ['<C-e>'] = cmp.mapping.abort(),
    ['<CR>'] = cmp.mapping.confirm({ select = true }),
  }),
  sources = cmp.config.sources({
    { name = 'nvim_lsp' },
    { name = 'vsnip' },
  }, {
    { name = 'buffer' },
  })
})

What you should see: with a language server running and attached to the buffer, pressing Ctrl-Space opens the menu with server-provided items, and Ctrl-E closes it. The confirm mapping accepts the highlighted item when select is true. If the menu stays empty, the LSP capabilities handoff is the first thing to check, because the README wires it through a separate call.

lua
local capabilities = require('cmp_nvim_lsp').default_capabilities()
vim.lsp.config('<YOUR_LSP_SERVER>', {
  capabilities = capabilities
})
vim.lsp.enable('<YOUR_LSP_SERVER>')

The placeholder <YOUR_LSP_SERVER> is literal in the README and must be replaced with the name of a server you have enabled. The vim.lsp.config and vim.lsp.enable functions are the newer Neovim LSP entry points, so this example assumes a Neovim recent enough to provide them.

The keymap presets are explicitly not a stable contract

This is the limitation most likely to bite a team that standardizes on a shared Neovim configuration. The README states that cmp.mapping.preset.* is pre-defined configuration aiming to mimic Neovim's native behavior, and that it can be changed without announcement, followed by the instruction to manage key-mapping yourself. That is unusually direct. A minor update can alter how a preset behaves, and the project has told you in advance that it will not treat that as a breaking change.

The practical consequence is that the preset is a starting point, not an interface. The README's own example already overrides parts of it by passing a table to cmp.mapping.preset.insert, binding Ctrl-B and Ctrl-F to cmp.mapping.scroll_docs with -4 and 4, and Ctrl-Space, Ctrl-E and Enter to complete, abort and confirm. If your configuration depends on the preset's default behavior for keys you did not bind, you are depending on something the documentation says may move.

The second limitation is structural. Because sources are external, the quality of your completion depends on plugins outside this repository. The README does not describe a fallback when a source plugin is missing or unmaintained; a name in the sources table that has no matching plugin simply contributes nothing.

How nvim-cmp differs from a bundled completion client

The closest comparison in the search data is coc.nvim, and the difference is architectural rather than cosmetic. coc.nvim is a Node.js client that manages its own language servers and its own extension ecosystem; installing it gives you a server manager, a completion UI and a set of extensions in one package. nvim-cmp has no server management layer. It plugs into the LSP client Neovim already has, and it expects you to decide which servers run and how they are configured. If you want one install to produce a working completion setup, coc.nvim's model is the one that matches that expectation.

Against Neovim's native completion, the trade is control. Native completion requires no plugin and no Lua configuration. nvim-cmp adds a Lua-configurable menu, source ordering through cmp.config.sources, per-filetype setups such as the gitcommit example in the README, and separate cmdline configuration for '/', '?' and ':'. The README also notes that the buffer source for '/' and '?' will not work if you enabled native_menu. That is a concrete conflict between the two approaches, not a preference.

The README's concept list claims full support for LSP completion related capabilities, customizability via Lua functions, smart handling of key mappings and no flicker. Those are the project's own claims, and the mechanism behind the LSP claim is the default_capabilities() handoff shown earlier.

Maintenance, licence and what an upgrade costs you

The repository is not archived, and the last push was on 2026-07-09. Releases are sparse: v0.0.2 was tagged on 2025-01-07 and v0.0.1 on 2022-08-14. That pattern tells you the version tags are not the distribution channel. Most users track the main branch through their plugin manager, which means the upgrade unit is a commit range, not a release.

The README handles this directly. It points to a GitHub issue that documents breaking changes for nvim-cmp and asks readers to subscribe to it to be notified of upcoming breaking changes. There is no changelog file in the top-level repository entries, and no migration guide. The stated support posture is also worth reading before filing anything: the README calls this a hobby project, welcomes bug reports, and says not to expect a fix unless you provide minimal configuration and steps to reproduce.

The licence is MIT. That permits commercial and private use and modification, and it requires the copyright notice and permission notice to be included in copies or substantial portions. It comes with no warranty. Whether that fits a given organization's policy is a question for that organization; the plugin is a Neovim configuration dependency rather than a distributed product, so the practical obligation usually attaches only if you vendor or redistribute the code.

Development tooling is visible in the repository. The Makefile defines lint as luacheck ./lua and test as vusted --output=gtest ./lua, with pre-commit and integration targets running both. If you plan to patch nvim-cmp locally, that is the loop the maintainer uses.

Editorial conclusion

Adopt nvim-cmp if you already run Neovim's built-in LSP client and want to choose each completion source yourself, and you are willing to keep your own keymaps because the cmp.mapping.preset.* tables are documented as changeable without announcement. Do not adopt it if you want one plugin that completes from LSP, buffers and paths out of the box, or if you refuse to configure a snippet engine, since cmp.setup requires the snippet.expand function. Before committing, verify three things: that your Neovim version supports the vim.lsp.config and vim.lsp.enable calls shown in the README, that the source plugins you intend to use are still listed in the project's source wiki, and that you are comfortable pinning a commit, because the README points breaking changes at a single GitHub issue rather than a changelog.

Frequently asked questions

What is nvim-cmp?

It is a completion engine plugin for Neovim written in Lua. It handles the completion menu and key mappings, while the actual candidates come from external source plugins that you install separately.

What does nvim-cmp do?

It draws the completion menu, orders candidates from the sources you configure, and manages keys while the menu is open. The README lists full support for LSP completion related capabilities, customizability via Lua functions, smart handling of key mappings and no flicker.

How to install nvim-cmp?

The README's recommended configuration uses vim-plug, adding Plug 'hrsh7th/nvim-cmp' along with the source plugins you want, then calling cmp.setup in a lua <<EOF block. The repository also contains an nvim-cmp-scm-1.rockspec, so a LuaRocks installation path exists, though the README does not document it.

How to setup nvim-cmp?

You call cmp.setup with a table containing a snippet.expand function, a mapping table, and a sources table built with cmp.config.sources. The snippet.expand function is marked REQUIRED in the README, and it must call the snippet engine you installed, such as vsnip or luasnip.

How to use nvim-cmp?

After setup, the mappings you define control the menu: the README example binds Ctrl-Space to cmp.mapping.complete, Ctrl-E to cmp.mapping.abort, and Enter to cmp.mapping.confirm with select set to true. Candidates appear from whichever sources you listed, for example nvim_lsp first and buffer as a fallback.

How does nvim-cmp compare with coc.nvim?

coc.nvim is a Node.js client that manages its own language servers and extensions, so one install produces a working setup. nvim-cmp has no server management layer: it connects to Neovim's built-in LSP client through cmp_nvim_lsp's default_capabilities() and leaves server configuration to you.

Official sources

  1. hrsh7th/nvim-cmp on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
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/hrsh7th-nvim-cmp.svg)](https://hysenlabs.com/projects/hrsh7th-nvim-cmp)