Five structural decisions that shape a Neovim plugin's future

A pattern shows up when a plugin author reopens their own plugin a year after last touching it. Half the design choices in the code they wrote themselves are now inscrutable. Why does setup() bail early when called twice? Why is the autocmd group named the way it is? Why does the picker call path have a pcall wrapped around it and a vim.ui.select fallback beneath? The uncomfortable answer, most of the time, is that those choices weren’t really decisions when they were made. They were the shape the code happened to take when a specific problem forced it. Five of these shapes recur in every plugin worth shipping, and each one has a recommended default that becomes obvious only in retrospect. Make them consciously in the first hour of work and the plugin absorbs future features without contortion. Skip them, and you’ll rediscover them in a year — usually as a rewrite. ...

July 18, 2026 · 10 min · Omar Crosby

The Neovim plugin directory structure that scales

A pattern shows up in almost every first attempt at a real plugin. The author has read the source of a plugin they respect, sees its lua/ directory with eight submodules, a types.lua, a health.lua, an after/ftplugin/ file, and a full vimdoc under doc/. So they scaffold their own new plugin with the same shape on day one — a config.lua that reads no config, a types.lua with no types, an init.lua that just re-exports what the other files export. Two weeks later they can’t add a feature without also picking which of the empty scaffolding files it belongs in, and each choice feels arbitrary because there’s no pressure yet to justify it. ...

July 18, 2026 · 11 min · Omar Crosby

How Neovim actually loads a plugin

A pattern shows up in the way most people first install a Neovim plugin. They add a line to their plugin manager’s config — a URL, maybe a version pin — restart Neovim, and the plugin’s commands, keymaps, and behaviors just appear. The install feels like a black box: you handed the manager a name, the manager did something, the plugin exists. The black box is smaller than it looks. Underneath every plugin manager is Neovim’s own built-in plugin discovery, and it’s mechanical, deterministic, and short enough to explain in a single post. Once you know what fires when, the directory structure of any plugin — including one you write yourself — stops looking like a convention someone made up and starts looking like a straightforward consequence of Neovim’s rules. ...

July 18, 2026 · 9 min · Omar Crosby

Your first Neovim plugin

A pattern shows up in almost every Neovim user I talk to who has been using the editor for a year or two. They have their config version-controlled. They know their leader mappings by feel. They can name ten plugins they rely on daily. And they’ve been meaning to write one of their own for months. The gap between using a plugin and writing one feels larger than it actually is. Not because the work is hard, but because nothing in the getting-started path makes the shape of a plugin obvious. Every tutorial jumps to configuration DSLs, package managers, or a distribution’s opinion about layout. The mechanics underneath all of that — how Neovim actually finds and loads your code — stay invisible right up until you try to write a plugin, at which point they become the whole problem. ...

July 18, 2026 · 8 min · Omar Crosby