coc-snippets brings UltiSnips, snipmate and VSCode snippets into Neovim
Snippets solution for coc.nvim
At a glance
- What is it?
- coc-snippets is a coc.nvim extension that loads UltiSnips, snipmate, VSCode and massCode snippet sources, offers them as completion items and lets you jump between placeholders. It suits Neovim users who have snippet collections already, and it inherits the parts of UltiSnips that a Vimscript engine can offer.
- Who is it for?
- coc-snippets suits a Neovim or Vim user who already maintains snippets in UltiSnips, snipmate or VSCode format and wants them to work inside coc.nvim with completion and placeholder jumping. It is the wrong tool for someone who wants the UltiSnips feature set unchanged, because the extension documents exactly which features it will not support, including shell code with a custom shebang and all snippet actions, and the wrong tool for a plain Neovim user with no coc.nvim.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 54 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 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One extension, several snippet dialects
coc-snippets is the snippets solution for coc.nvim, and its main achievement is not inventing a snippet format but accepting the ones people already have. The README lists what it can load: UltiSnips snippets, snipmate snippets, VSCode snippets from coc.nvim extensions, VSCode snippets from custom directories, VSCode snippets from ${workspaceFolder}/.vscode, UltiSnips snippets from a configured folder, and massCode snippets from a running massCode application, which is disabled by default.
That last one is unusual. massCode is a desktop snippet manager, and the extension can read from a live instance of it, plus create snippets through the snippets.editMassCodeSnippets command. It is the only source in the list that is not a set of files on disk.
From there the extension presents the snippets as completion items, so they appear in the normal coc.nvim completion list rather than behind a separate trigger. It also provides the expand and expandOrJump keymaps, and a snippets list for editing, with the snippets.editSnippets command opening the user's snippets for the current filetype.
The design goal behind that is a unification. The README's own reasons list the same keys for jumping placeholders regardless of which dialect the snippet came from, nested snippet support, and asynchronous behaviour that never slows you down. A user with a mixed collection, some UltiSnips from a colleague and some VSCode snippets from a project template, gets one set of key bindings rather than two.
The Python requirement is the first thing to check
UltiSnips snippets are code, and that code runs in Python inside the editor. The README is direct about the requirement: the UltiSnips provider needs pythonx support on (neo)vim, and it gives you the command to check:
:echo has('pythonx')On Neovim the check is different, and the README asks you to run:
:checkhealthIf the feature is missing, the documented fix is to install pynvim and make sure a Python 3 provider is installed for Neovim. For Vim 8 the diagnostic is a Python expression:
:pyx print(1)and if that throws, the editor is either not compiled with Python support or the Python dynamic library it needs is missing or broken.
There is a fallback for people who cannot or will not fix their editor build. The README notes that an error is shown when pythonx cannot work, and that you can disable UltiSnips support with the snippets.ultisnips.enable setting set to false in your configuration file. The other snippet dialects do not need Python.
The README also flags a subtler trap: some Python code may require a Python feature that the interpreter linked into your editor does not support, and the error will be thrown in that case. So a working pythonx is necessary but not sufficient, which matters if you have snippets that use modern Python.
Key mappings and the VSCode-style tab
The extension ships plug mappings rather than forcing key choices, and the README gives the set. The expand mapping is plugged to coc-snippets-expand, the visual selection mapping to coc-snippets-select, and there is a combined coc-snippets-expand-jump for insert mode that expands when there is something to expand and jumps to the next placeholder otherwise. The README also notes that you cannot use noremap with Plug key-mappings, which is a small but frequent source of broken configurations.
A worked example binds the control keys:
" Use <C-l> for trigger snippet expand.
imap <C-l> <Plug>(coc-snippets-expand)
" Use <C-j> for select text for visual placeholder of snippet.
vmap <C-j> <Plug>(coc-snippets-select)
" Use <C-j> for jump to next placeholder, it's default of coc.nvim
let g:coc_snippet_next = '<c-j>'The more interesting part is the VSCode-like tab behaviour, which the README implements as a conditional expression mapping with a helper function that checks whether the previous character was whitespace. The logic is: confirm the visible completion popup if there is one, otherwise expand or jump if that is possible, otherwise insert a literal tab if the previous character was whitespace, otherwise refresh the completion list. The function that decides the whitespace case compares the character before the cursor against a whitespace pattern, and the mapping ends by setting g:coc_snippet_next to the tab key.
The README also flags that from coc.nvim 0.0.82 onwards, functions starting with coc#pum should be used for custom completion, and the package manifest requires coc 0.0.82 or later, so the mapping targets the current API.
The UltiSnips features that are deliberately missing
The README keeps a checklist of UltiSnips features, and it is the most useful part of the documentation for anyone deciding whether to move a snippet collection. Most of the familiar features are marked as supported: position checking of the trigger option including b, w and i, executing vim, python and shell code in a snippet, the extends, priority and clearsnippets commands, visual placeholders, placeholder and variable transforms, expression snippets, automatic trigger snippets, context snippets, loading snipmate snippets, the replacement string form, updating the Python code block after a placeholder changes, the m option for trimming trailing whitespace, and reformatting of snippet options including t and s.
Two entries are marked as things that will not be supported. The first is executing shell code with a custom shebang. The second is the actions pre_expand, post_expand and jump, and the README adds in parentheses that they cannot be supported. The properties that go with snip.expand_anon() and the other UltiSnips actions are in the same category.
Two notes explain the consequences of that gap. The first says that snip.expand_anon expands the snippet asynchronously using a timer when used with pre_expand and post_expand, which means the state is lost in your Python script, and that this should only happen in some rare cases. The second is a compatibility trap that will bite anyone porting a large collection: Python regular expressions in snippets are converted to JavaScript regular expressions, and some patterns cannot be supported, including the extended and dotall flags, the end-of-string anchor, and the conditional group form.
So a snippet set that relies on those will load and then fail at expansion time rather than at load time.
Commands, functions and the options you can turn
Beyond expansion, the extension exposes a small set of commands and helper functions that other parts of your configuration can build on.
The commands are listed in the README. :CocList snippets opens the snippets list used by the current buffer, with the last used item preselected. :CocCommand snippets.openSnippetFiles chooses and opens a snippet file used by the current document, snippets.editSnippets opens your user UltiSnips snippets for the current filetype, snippets.openOutput opens the output channel, and snippets.addFiletypes adds extra filetypes to the current buffer. There is also the buffer-local variable b:coc_snippets_filetypes, which adds filetypes when a buffer is created, for cases where the automatic filetype detection is wrong.
Three Vimscript functions exist for conditional mappings. coc#expandable() returns 1 when a snippet expansion is possible, coc#jumpable() returns 1 when a snippet is active and the next placeholder can be jumped to, and coc#expandableOrJumpable() returns 1 for either. These are what the tab mapping is built on, and they are also what you need if you want your own key to behave differently inside a snippet than outside one.
The options are few. snippets.priority sets the completion source priority of snippets, with a default of 90, and a second option configures the command used when opening the snippet editor. Because snippets are a completion source like any other, that priority number determines where they appear relative to your language server results, which is the single knob most users will want to adjust.
An extension with no releases and a plain build
The repository is not archived and the last push was on 2026-08-30. There are no GitHub releases, so the version to install comes from the extension manager rather than from a tag.
The version in the package manifest reads 3.4.10, and the manifest shows a small and conventional extension. The main entry is lib/index.js, the publisher is chemzqm, and the extension activates on everything, with an activation event of a single asterisk. The build is esbuild, driven by a script in the repository root, and the same script runs on prepare, which means a plain npm install compiles the extension.
The scripts also show how the project is tested. The test target runs a build and then coc-test over the test files, and there are parallel targets for integration tests against Neovim and against Vim specifically, with the --nvim and --vim flags. The coc-test configuration sets one user setting, disabling snippets.ultisnips.pythonPrompt, which tells you that the UltiSnips prompt path is switched off during test runs.
The repository layout matches a Vim extension with a Vimscript side: there are ftplugin, syntax and python directories alongside the TypeScript in src, an esbuild.js, a tsconfig.json, a CHANGELOG.md and a test directory.
On the licence, the repository carries no recognised licence identifier in its metadata and the README does not state one. There is a LICENSE file at the root, but a project that ships code and whose manifest carries no licence field is worth checking before you vendor any of it into a product of your own.
Editorial conclusion
coc-snippets suits a Neovim or Vim user who already maintains snippets in UltiSnips, snipmate or VSCode format and wants them to work inside coc.nvim with completion and placeholder jumping. It is the wrong tool for someone who wants the UltiSnips feature set unchanged, because the extension documents exactly which features it will not support, including shell code with a custom shebang and all snippet actions, and the wrong tool for a plain Neovim user with no coc.nvim. Before you adopt it, run the health check the README describes to confirm pythonx support, since UltiSnips snippets are executed in Python, and read the unsupported feature list in the repository before you migrate a large snippet set.
Frequently asked questions
How do I install coc-snippets?
The README gives a single command inside your vim or neovim: :CocInstall coc-snippets. The extension is published for coc.nvim and the package manifest requires coc 0.0.82 or later.
Which snippet formats does coc-snippets support?
UltiSnips, snipmate, VSCode snippets from coc.nvim extensions, from custom directories and from the .vscode folder in the workspace, UltiSnips from a configured folder, and massCode snippets read from a running massCode application, which is disabled by default.
Do UltiSnips snippets need Python support in the editor?
Yes. The UltiSnips provider needs pythonx support on (neo)vim, which you can check with :echo has('pythonx') in vim or :checkhealth in neovim, and pynvim needs to be installed if it is missing. UltiSnips support can be turned off with the snippets.ultisnips.enable setting set to false.
Which UltiSnips features are not supported?
The README lists two: executing shell code with a custom shebang, and the snippet actions pre_expand, post_expand and jump together with the properties that go with snip.expand_anon(). It also warns that Python regular expressions in snippets are converted to JavaScript, so several Python-only pattern forms cannot be supported.
Official sources
Was this useful?