coc-clangd: the clangd language server wired into coc.nvim with a few extras
clangd extension for coc.nvim
At a glance
- What is it?
- coc-clangd is a TypeScript extension that connects the clangd language server to the coc.nvim plugin ecosystem, adding clangd's non standard extensions such as header and source switching, a status line file monitor and symbol info under the cursor. It is a small extension with a large configuration surface, and the hard part of using it is the compilation database rather than the plugin.
- Who is it for?
- coc-clangd fits a Neovim user who has already chosen coc.nvim for language intelligence and wants clangd's accuracy behind it, including the extensions clangd ships outside the official protocol. It does not fit a Neovim user on a built-in LSP client, or a C or C++ project that has no compilation database, because clangd's results depend on one.
- 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 22 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Five steps to a working clangd in Neovim
The extension connects coc.nvim to the clangd language server, and the quick start is five steps.
The first is to install Node.js, because coc.nvim and coc-clangd both run on Node. The second is to install coc.nvim, with the vim-plug route given as:
vim Plug 'neoclide/coc.nvim', {'branch': 'release'}and then running :PlugInstall in vim, with a pointer to the coc.nvim wiki for other options.
The third is to run :CocInstall coc-clangd inside vim. The fourth is to let the extension find the binary: it will try to find clangd from your $PATH, and if it is not found you can run :CocCommand clangd.install to install the latest release from GitHub. The fifth step is the one people skip: follow the clangd project setup documentation to generate compile_commands.json for your project.
That last step is where the extension's usefulness is won or lost. clangd is a language server that parses your project with the real compiler flags, and without a compilation database it is guessing, and a guess in C or C++ is wrong often enough to make the whole experience look broken.
The README carries one warning about configuration: if you have already configured clangd as a languageServer in coc-settings.json, you should remove it to avoid running clangd twice. Two language servers competing over the same buffers produce duplicated diagnostics and duplicated completions, and the fix is a one-line removal rather than anything the extension can detect.
The four extensions clangd adds beyond the protocol
clangd supports some extensions that are not in the official Language Server Protocol specification, and coc-clangd adds support for four of them.
The first is switching between a header and its implementation file, with the command :CocCommand clangd.switchSourceHeader, and a variant that opens the result in a split buffer via :CocCommand clangd.switchSourceHeader vsplit. For C and C++ work this is the feature that saves the most time, because the declaration and the definition are in different files and the editor cannot infer which one you meant.
The second is a file status monitor, which shows on the Neovim status line. That is the index state, the thing you are waiting for, made visible so you know whether to wait or to keep typing.
The third is describing the symbol under the cursor with :CocCommand clangd.symbolInfo, which resolves what the thing under the cursor actually is, its type and where it is declared.
The fourth is completions that adjust text near the cursor, for example correcting a . to an ->. That is a small thing to read and a large thing to notice, because it is the kind of correction that only works when the server understands the code around the cursor.
There is also a longer command list beyond the extensions. clangd.switchSourceHeader and clangd.symbolInfo are the two above, clangd.memoryUsage shows memory usage, clangd.ast shows the AST, clangd.install installs the latest clangd release from GitHub and clangd.update checks for updates.
Eleven configuration keys and the compilation database settings
Configuration is edited through coc.nvim's own commands, and the split between global and local is worth knowing. :CocConfig opens the global coc-settings.json, and :CocLocalConfig opens the local configuration for the project, which lives at $PROJECTROOT/.vim/coc-settings.json. A per-project setting is the right place for anything that differs between repositories, and the compilation database path is the setting most likely to differ.
The configuration table has eleven entries. clangd.enabled turns the extension on and is true by default. clangd.arguments passes arguments to the server and is empty by default. clangd.checkUpdates checks for language server updates on startup and is false by default, which is a sensible default since the check is a network call on every start.
Then there are four disable switches, all false by default: clangd.disableCompletion, clangd.disableDiagnostics, clangd.disableSnippetCompletion and clangd.disableProgressNotifications. The last of those is the one people reach for, because clangd's indexing progress notifications arrive repeatedly on a large project and can be noisy.
The compilation database settings are the important pair. clangd.compilationDatabasePath specifies the directory containing the compilation database and is empty by default. clangd.compilationDatabaseCandidates specifies directories that may contain it, and it supports the ${workspaceFolder} variable convention that the documentation links to the editor variables reference for.
The fallback is clangd.fallbackFlags, extra clang flags used to parse files when no compilation database is found, also empty by default. And clangd.path is the path to the clangd executable, defaulting to clangd, which is why putting clangd on the PATH is the simplest installation.
One setting is not in the table at all, because it belongs to coc.nvim rather than to this extension: semantic highlighting is disabled by default in coc.nvim and you enable it with semanticTokens.enable.
How the extension is packaged and built
The package is coc-clangd at version 0.33.0, with the description clangd extension for coc.nvim. The main entry point is lib/index.js, the license field is Apache-2.0 WITH LLVM-exception, and the engines field requires a coc version of ^0.0.80.
The build is a single esbuild script. The scripts are build, which runs node esbuild.js, watch, which runs the same with the watch flag, prepare, which also runs node esbuild.js so the bundle is built on install, format, which runs biome format over the source, and check, which runs biome check. The formatter is Biome rather than the older Prettier setup, and there is a.prettierrc file left in the repository alongside the biome.json configuration.
The activation events list the languages that start the extension, and the list is longer than you would expect for a C and C++ server: onLanguage:c, cpp, cuda, objc, objcpp, opencl, objective-c and objective-cpp. The CUDA and OpenCL entries are the ones that matter, because those are the cases where you would otherwise end up with a generic C or C++ server that does not understand the device-specific qualifiers.
The rootPatterns entry is how the extension decides a folder is a C or C++ project, and the patterns are.clangd,.clang-tidy,.clang-format, compile_commands.json and compile_flags.txt. That is a useful piece of implicit information: if you are wondering why the extension is not activating in a directory, one of these five files is what it is looking for.
The dev dependencies tell you what the project uses to test against real clangd binaries, with a clangd install package and a coc.nvim package, plus esbuild, fs-jetpack for file operations, TypeScript and the Biome tool. The extension is built with create-coc-extension, the scaffolding tool the README credits, and the README states it is built with it.
Where coc-clangd is the wrong choice
The first limitation is that it is an extension for coc.nvim specifically, and coc.nvim itself is a choice you have already made or not. If your Neovim setup uses the built-in LSP client that shipped with Neovim, or a different plugin entirely, then this extension does nothing for you and the underlying language server is the part you would install directly. The dependency on Node.js is part of the same bargain, since coc.nvim and this extension both run on it.
The second is the compilation database, and the extension cannot fix its absence. A project with a hand-rolled build system, an unusual cross-compilation setup or a generated source tree will need a tool to produce compile_commands.json, and the fallback flags exist precisely because that is hard in some cases. The good news is that clangd itself documents the project setup, and the bad news is that it is real work that the extension cannot do for you.
The third is the version surface. The extension pins an esbuild and a TypeScript version, a coc engine requirement, and a dev dependency on a specific coc.nvim prerelease build. It also depends on the clangd binary separately, and the checkUpdates setting is off by default, so a long-lived installation will drift between the extension and the server it drives unless someone watches that.
The fair comparison is with running clangd directly through a generic LSP client. The extension adds the four non standard commands, a status line indicator and the coc.nvim ecosystem around them, and it costs you a Node.js dependency and a version of the coc client to keep in step. If you use coc.nvim already, that is a good trade. If you do not, the extension is the wrong place to start.
Editorial conclusion
coc-clangd fits a Neovim user who has already chosen coc.nvim for language intelligence and wants clangd's accuracy behind it, including the extensions clangd ships outside the official protocol. It does not fit a Neovim user on a built-in LSP client, or a C or C++ project that has no compilation database, because clangd's results depend on one. Before installing, make sure clangd is not already configured as a languageServer in coc-settings.json, since that would run it twice, and generate compile_commands.json for the project before judging the results.
Frequently asked questions
How do I install coc-clangd in Neovim?
Install Node.js, install coc.nvim, run :CocInstall coc-clangd inside vim, and either put clangd on your PATH or run :CocCommand clangd.install to fetch the latest release from GitHub. Then generate compile_commands.json for your project following the clangd project setup documentation.
What does coc-clangd add on top of the plain language server protocol?
It adds support for clangd's own extensions: switching between a header and its implementation file with :CocCommand clangd.switchSourceHeader, a file status monitor on the Neovim status line, describing the symbol under the cursor with :CocCommand clangd.symbolInfo, and completions that adjust text near the cursor such as correcting a dot to an arrow.
What are the main coc-clangd configuration options?
clangd.enabled, clangd.arguments, clangd.checkUpdates, clangd.path for the executable, and the compilation database settings clangd.compilationDatabasePath, clangd.compilationDatabaseCandidates and clangd.fallbackFlags. There are also disable switches for completion, diagnostics, snippet completion and progress notifications. Global settings live in coc-settings.json via :CocConfig and project settings in $PROJECTROOT/.vim/coc-settings.json via :CocLocalConfig.
What licence is coc-clangd released under?
Apache 2.0 with the LLVM Exception, described as the standard LLVM license. The package manifest records the same as Apache-2.0 WITH LLVM-exception, and the repository carries a LICENSE file.
Which languages does coc-clangd activate for?
The activation events cover C, C++, CUDA, Objective-C, Objective-C++, OpenCL and the dash forms of the Objective-C languages, so the extension starts for device code as well as ordinary C and C++ files.
Official sources
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.
[](https://hysenlabs.com/projects/clangd-coc-clangd)Was this useful?