Setup coc.nvim
Get completion, diagnostics, and code navigation working in three focused steps.
Check your environment
You need Node.js and either a supported Neovim or Vim.
node --versionnvim --versionvim --versionInstall with one command
Choose your editor, review the command, then run it in a terminal.
Quick Script InstallRecommended
Uses the selected editor's native pack mechanism. Run again anytime to update.
Review what it runs before executing: view installer source.
curl -fsSL https://cocnvim.com/install-coc.sh | bash -s -- --editor=nvim
The script checks Node.js and Neovim, detects another coc.nvim installation, then shows every planned path before confirmation. It installs to ${XDG_DATA_HOME:-~/.local/share}/nvim/site/pack/coc/opt/coc.nvim and the Neovim init file and preserves an existing native-pack copy as .backup-*. It adds one idempotent packadd coc.nvim entry when the config does not already load coc.nvim. Use --no-config / -NoConfig to leave config unchanged.
Prefer a plugin manager, native package, or source build? See all installation methods.
Enable the essentials
Select language support on the left and copy the generated editor setup.
Language support
0 selectedOptional. Selected extensions are installed automatically when coc.nvim starts.
| 1 | -- Add to ~/.config/nvim/init.lua |
| 2 | vim.g.coc_global_extensions = { } |
| 3 | |
| 4 | vim.opt.backup = false |
| 5 | vim.opt.writebackup = false |
| 6 | vim.opt.updatetime = 300 |
| 7 | vim.opt.signcolumn = 'yes' |
| 8 | vim.opt.laststatus = 2 |
| 9 | |
| 10 | -- Show coc.nvim status, including extension installation progress |
| 11 | vim.opt.statusline:prepend('%{coc#status()}') |
| 12 | |
| 13 | local keyset = vim.keymap.set |
| 14 | function _G.check_back_space() |
| 15 | local col = vim.fn.col('.') - 1 |
| 16 | return col == 0 or vim.fn.getline('.'):sub(col, col):match('%s') ~= nil |
| 17 | end |
| 18 | |
| 19 | -- Trigger completion with Tab and navigate the completion menu |
| 20 | local opts = { silent = true, noremap = true, expr = true, replace_keycodes = false } |
| 21 | keyset('i', '<TAB>', 'coc#pum#visible() ? coc#pum#next(1) : v:lua.check_back_space() ? "<TAB>" : coc#refresh()', opts) |
| 22 | keyset('i', '<S-TAB>', [[coc#pum#visible() ? coc#pum#prev(1) : "\<C-h>"]], opts) |
| 23 | keyset('i', '<CR>', [[coc#pum#visible() ? coc#pum#confirm() : "\<C-g>u\<CR>\<c-r>=coc#on_enter()\<CR>"]], { silent = true, expr = true }) |
| 24 | |
| 25 | -- Diagnostics and code navigation |
| 26 | keyset('n', '[c', '<Plug>(coc-diagnostic-prev)', { silent = true }) |
| 27 | keyset('n', ']c', '<Plug>(coc-diagnostic-next)', { silent = true }) |
| 28 | keyset('n', 'gd', '<Plug>(coc-definition)', { silent = true }) |
| 29 | keyset('n', 'gy', '<Plug>(coc-type-definition)', { silent = true }) |
| 30 | keyset('n', 'gi', '<Plug>(coc-implementation)', { silent = true }) |
| 31 | keyset('n', 'gr', '<Plug>(coc-references)', { silent = true }) |
| 32 | keyset('n', '<leader>rn', '<Plug>(coc-rename)', { silent = true }) |
The extension list is optional. coc.nvim provides the client; language features become available after an extension or manually configured server starts.
Restart your editor and try it
Open a file for a selected language, then run :CocInfo to inspect the coc.nvim runtime. Then follow one of the examples below to verify that language analysis works.
Your first TypeScript project
After installing coc.nvim and the completion mappings above, use this isolated example to check language features. It needs no npm dependencies or application framework. Run these commands in a terminal, choosing a new directory if this name already exists:
| 1 | mkdir coc-typescript-example |
| 2 | cd coc-typescript-example |
| 3 | printf '%s\n' '{"compilerOptions":{"strict":true,"noEmit":true},"include":["index.ts"]}' > tsconfig.json |
| 4 | printf '%s\n' 'const user = { name: "Ada", age: 36 };' 'const age: number = "36";' 'user.name.toUpperCase();' > index.ts |
| 5 | nvim index.ts |
Use vim index.ts instead if you use Vim. In the editor, run the installation command and wait for it to finish:
| 1 | :CocInstall coc-tsserver |
- Run
:set filetype?; this file should betypescript. Reopen the file after extension installation if the language service has not activated. - Run
:CocDiagnostics. The second line deliberately assigns a string to a number. Expect a diagnostic explaining that string is not assignable to number. - Replace
"36"with36, save, and wait for analysis. The diagnostic should disappear. Do not suppress diagnostics to make this check pass. - On a new line, enter Insert mode and type
user.. Member suggestions should includenameandage. Choosenameusing the completion mappings above, then remove the temporary line if you leave it incomplete.
If diagnostics work but accepting a suggestion does not, check the Tab/Enter mappings. If neither works, inspect :CocList extensions and :CocOpenLog before changing project settings. Follow completion troubleshooting or the coc-tsserver usage notes.
Diagnostics and completion reproduced on 2026-09-11 with Neovim 0.12.4, Node.js 26.5.0, coc.nvim revision 00993bae8 and coc-tsserver 2.4.1: error 2322 on line 2, then no diagnostics after correcting the value; member suggestions included age and name, and Tab/Enter accepted user.name. This checks language analysis, not a production build. The example uses the extension’s bundled TypeScript; existing projects may select a different SDK. See the extension documentation for version selection.
Python: check the environment and a type error
This example separates two common failures: an import available in a different Python environment, and an invalid assignment in your source. Use a new directory so the example does not change an existing project. The terminal commands below target macOS/Linux and require Python with venv support.
| 1 | mkdir coc-python-example |
| 2 | cd coc-python-example |
| 3 | python3 -m venv .venv |
| 4 | .venv/bin/python -m pip install packaging |
| 5 | source .venv/bin/activate |
| 6 | python -c "import sys; from packaging.version import Version; print(sys.executable); print(Version('1.2.0'))" |
| 7 | nvim example.py |
The terminal check should print a Python executable inside this project’s .venv and 1.2.0. If the import fails here, resolve the dependency installation before debugging the editor. Use vim example.py for Vim. In Windows PowerShell, create the environment with py -m venv .venv, use .venv\Scripts\python.exe for pip and run .venv\Scripts\Activate.ps1 before opening the editor.
Make analysis observable
Install with :CocInstall coc-pyright. Save the following contents to example.py:
| 1 | from packaging.version import Version |
| 2 | |
| 3 | count: int = "three" |
| 4 | print(Version("1.2.0"), count) |
For this isolated project, create .vim/coc-settings.json with the following setting. In an existing project, merge the key instead of replacing its configuration. Reopen the editor from the activated environment after saving the configuration.
| 1 | { |
| 2 | "python.analysis.typeCheckingMode": "basic" |
| 3 | } |
- Check
:set filetype?reportspython, then run:CocDiagnostics. Expect an incompatible-assignment diagnostic oncount. The packaging import should resolve. - Replace
"three"with3, save and wait for analysis. The assignment diagnostic should disappear. - Run
python example.pyin the same activated terminal. After the correction, expect1.2.0 3. This checks the interpreter can import and execute the sample; Pyright itself does not run your application.
If the terminal import works but the editor import fails
Open :CocCommand workspace.showOutput and select Pyright. Compare its “Using python from” path with the terminal’s executable. Check :echo $VIRTUAL_ENV and :echo $CONDA_PREFIX inside the affected editor. Activating a different environment in another terminal cannot update an already running editor.
Close that editor and reopen it from the terminal where the import check passed. In coc-pyright 1.1.414, detected environments—including inherited VIRTUAL_ENV/Conda and project environment discovery—take precedence over the fallback python.pythonPath setting. If you configure that fallback, use the intended executable’s absolute path and confirm the result in the output channel.
If there are no language features at all, inspect the extension and language-server startup first. A missing Pyright server file requires repairing the extension installation; installing a Python package cannot repair that startup failure. Continue with the language-server troubleshooting steps.
Reproduced on 2026-09-11 with Neovim 0.12.4, Node.js 26.5.0, coc.nvim 00993bae8, Python 3.14.6, coc-pyright/Pyright 1.1.414 and packaging 26.3: an empty environment produced reportMissingImports and reportAssignmentType; the selected environment cleared the import error, and correcting count cleared the remaining diagnostic. Environment selection checked in coc-pyright 1.1.414. See the extension documentation for managed environments and optional tools. Shell commands shown here are for a disposable example; Windows commands have not been exercised in this check.