LuaSnip: the snippet engine that speaks LSP natively and Lua when it must
Snippet Engine for Neovim written in Lua.
At a glance
- What is it?
- LuaSnip is an Apache-2.0 snippet engine for Neovim written in Lua, offering tabstops, choices, conditional expansion, dynamic snippet creation, regex and autotriggers, and Treesitter based filetype resolution. It parses LSP style snippets directly, as VSCode packages or SnipMate collections, so 95 percent of snippets need no Lua, while the full power remains a Lua function away. The current release line is 2.5.0.
- Who is it for?
- Choose LuaSnip when snippets should be interactive programs rather than text shortcuts, choices, conditionals, dynamic nodes, functions reading the buffer, and when compatibility with the LSP and VSCode ecosystems matters, since importing existing collections is a loader call. Choose a simpler engine if plain text templates cover the need, since LuaSnip's depth costs configuration attention.
- 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 135 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
Ninety-five percent LSP syntax, the rest in Lua
The one drawback the project names is also its design summary, snippets that make use of the entire functionality of this plugin have to be defined in Lua, but 95 percent of snippets can be written in LSP syntax. That split defines the audience, most users live entirely in the portable LSP style format that language servers already speak, while the Lua escape hatch exists for the cases no declarative format can express. The engine parses LSP style snippets either directly in Lua, as a VSCode package, or as a SnipMate snippet collection, and it expands LSP snippets in completion integrations with nvim-compe or its successor nvim-cmp through cmp_luasnip, which is how snippets flow from language servers into the editor. The Fast entry on the feature list is a claim rather than a benchmark, but it sits first among the trigger features for a reason, an autotriggered engine that hesitates on every keystroke would be unusable, so latency is part of the design brief.
Three loaders for three ecosystems
Loading follows the format you already have. The VS Code loader, require("luasnip.loaders.from_vscode").lazy_load(), picks up snippets from any installed plugin providing them, with friendly-snippets named as the canonical collection, and custom directories work by passing paths to the same function, with the one mandatory rule that the directory carries a package.json. The SnipMate loader mirrors it, from_snipmate lazy_load, and the format is simple enough that custom snippets mean creating a snippets directory in your runtimepath with files named for the filetype, with honza's vim-snippets as the inspiration catalog. Snippets loaded this way are filetype specific by construction, matching files to buffers automatically. The lazy in lazy_load is load-time behavior worth its name, snippets arrive on startup or on first use rather than all at once, which keeps configuration time flat as collections grow into the thousands of snippets a polyglot setup accumulates.
Choices, dynamics, and Treesitter at the cursor
The node types go well past static text. Choices let a tabstop cycle through alternatives inside the snippet, conditional expansion includes or excludes parts based on runtime state, text transformations run Lua functions over node content, and dynamic snippet creation generates nodes from functions evaluated at jump time, the machinery for snippets that react to what was typed into earlier nodes. Nested snippets expand inside snippets, and snippet history lets you jump back into older snippets after leaving them, the undo of snippet navigation. Filetype resolution itself is clever, using Treesitter to determine the filetype at the cursor, so a Markdown buffer with embedded code gets the right snippets inside the fence, not the buffer's outer type.
Regex triggers, autotriggers, postfix snippets
Triggering covers the spectrum from explicit to invisible. Regex triggers match patterns rather than fixed words. Autotriggered snippets expand the moment their pattern is typed, no keypress confirm needed, the behavior pattern for things like arrow functions that should not require a Tab. Easy postfix snippets round out the list, the style where typing an expression then a suffix transforms it, borrowed from IDE culture. Combined with the node types, the trigger modes let a snippet appear exactly when its context is satisfied and never otherwise, which is the difference between a snippet engine people enable selectively and one they switch off after a week of false expansions.
Installing with a jsregexp side build
Installation goes through any plugin manager, pinned to the release line, with the lazy form:
{
"L3MON4D3/LuaSnip",
-- follow latest release.
version = "v2.*", -- Replace <CurrentMajor> by the latest released major (first number of latest release)
-- install jsregexp (optional!).
build = "make install_jsregexp"
}with packer and vim-plug equivalents shown beside it. Versioning is semantic with stated leeway, big patches might end up as a Minor version, and the recommendation is to follow the latest Major release and watch the repository for new ones. The jsregexp build needs care on two platforms, Windows requires a C compiler and make, with the CC variable set explicitly if the compiler is not gcc, clang or zig, and Git's bin directory on PATH for make's shell, while FreeBSD needs GNU make installed as gmake since the Makefile does not align with BSD make syntax.
Keymaps in Vim script or Lua
Two keymap styles are documented for the two kinds of configuration. The Lua form maps expand, jump forward, jump backward and choice cycling separately:
local ls = require("luasnip")
vim.keymap.set({"i"}, "<C-K>", function() ls.expand() end, {silent = true})
vim.keymap.set({"i", "s"}, "<C-L>", function() ls.jump( 1) end, {silent = true})
vim.keymap.set({"i", "s"}, "<C-J>", function() ls.jump(-1) end, {silent = true})
vim.keymap.set({"i", "s"}, "<C-E>", function()
if ls.choice_active() then
ls.change_choice(1)
end
end, {silent = true})The Vim script form binds Tab to expand or jump conditionally, Shift-Tab to jump backward, and Ctrl-E for choices. For the popular super-tab pattern where Tab does completion and snippets, the nvim-cmp wiki carries an example mapping, the integration point most new configurations copy.
Tested against three Neovim generations
The engineering behind the plugin shows in its Makefile, which clones Neovim once and creates git worktrees for master, v0.9.0 and v0.12.0, the rationale documented inline, switching between versions requires a full distclean rebuild that takes a lot of time, so parallel worktrees keep three testable targets simultaneously, covering the minimum supported 0.9 through the current line. A flake.nix provides the Nix development environment, stylua enforces formatting, and DOC.md plus Examples/snippets.lua serve as the extended manual. The project hosts a Matrix room for discussion, and releases are steady, v2.4.0 in May 2025, v2.4.1 in November 2025 and v2.5.0 on 2026-04-05, with the last push on 2026-05-19. The repository also ships ftplugin, syntax and plugin directories alongside the lua sources, the full skeleton of a well behaved Neovim plugin rather than a bare lua module, which is why filetype detection and highlighting integrate without user glue.
Editorial conclusion
Choose LuaSnip when snippets should be interactive programs rather than text shortcuts, choices, conditionals, dynamic nodes, functions reading the buffer, and when compatibility with the LSP and VSCode ecosystems matters, since importing existing collections is a loader call. Choose a simpler engine if plain text templates cover the need, since LuaSnip's depth costs configuration attention. Before adopting, pin to the latest major tag with your plugin manager as the project recommends, run make install_jsregexp if you use LSP style transformations, note the Windows C compiler requirement and the FreeBSD gmake requirement for that step, and start from DOC.md and Examples/snippets.lua, which the project treats as the real manual.
Frequently asked questions
what does luasnip do?
LuaSnip is a snippet engine for Neovim written in Lua, providing tabstops, choices, conditional expansion, nested and dynamic snippets, text transformations through Lua functions, regex and autotriggers, postfix snippets, and snippet history. It parses LSP style snippets, VSCode packages and SnipMate collections, and expands LSP snippets through nvim-cmp via cmp_luasnip.
how to install luasnip?
Install with your plugin manager pinned to the release line, for example version = "v2.*" in lazy.nvim with build = "make install_jsregexp" for the optional regex transformations support, or the equivalent tag and do settings in packer or vim-plug. Neovim 0.9 or newer is required.
how to use luasnip?
Map expand, jump and choice keys, the Lua example binding Ctrl-K to expand, Ctrl-L and Ctrl-J to jump forward and backward, and Ctrl-E to change choices, then load snippets through the VSCode or SnipMate loaders with lazy_load. DOC.md and Examples/snippets.lua document the loaders and the full snippet syntax.
What is the difference between LuaSnip and friendly-snippets?
They complement rather than compete, friendly-snippets is a community collection of VSCode style snippets while LuaSnip is the engine that expands them. Install friendly-snippets and call require("luasnip.loaders.from_vscode").lazy_load() to load its snippets into LuaSnip.
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/l3mon4d3-luasnip)