I'm really looking forward to this. I hope it helps push the nvim plugin community into lazy loading plugins by default instead of relying on a complex plugin manager like lazy. The nvim docs have a little note related to this[1].
I'm quite a fan of the nvim-neorocks plugin best practices as well[2]. In fact it seems like part of them got merged recently[3] hahaha.
The neovim model of using setup() makes lazy loading a bit trickier than traditional Vim.
Lazy loading is much easier with Vim’s model of configuring by setting variables. You just set variables in init.vim, and the plugin can auto-load when one of its functions is executed.
With lua this requires more orchestration; if many autocmd refer to the same plugin, they all need to explicitly remember to call setup().
Neovim provides the same mechanisms as Vim for Lua plugins.
The problem (and part of my motivation for writing the nvim-best-practices document) is that not enough plugins use them.
Edit: The Neovim setup antipattern is the Lua equivalent of writing Vimscript functions in autoload and asking users to call them in their configs instead of doing so automatically.
The settings variable convention is not good, uses random variable prefixes. A new convention is needed, then the ball can start rolling on that. Until then the lazy nvim and/or setup paradigm is useful.
I feel like I have to migrate to a new (Neo)Vim package manager about once every 3 or so years. I think my path has been: pathogen -> Vundle -> vim-plug -> lazy.nvim. Hopefully, this the last VIM package manager?
Plug still gets the job done imo. But I'm also hopeful that since this one is builtin to the language it'll likely be end-game worthy for lots of users. I have tried it out and had a painless experience though I never did anything fancy like lazy offered.
Luckily this is the built in, official, blessed one. So it’s likely going to be the most widely supported and available. (Maybe not most feature rich though)
Lazy.nvim seems pretty triumphant. But yeah a lot of others are also supported by various plugins. Some unity would be nice, abstractly. But man, it's hard to have faith we're going to get as anything good fast and reliable as lazy.nvim. it could happen though!
Every plugin manager I've used since Pathogen has seemed "triumphant" at the time. I think they've all been reliable enough and everytime I think well this will be the last time I change that.
I currently have a Packer config on one machine and Lazy on another and honestly don't know why I bothered switching to Lazy. What I really crave is simplicity so if NeoVim builds every thing in I think it will be good enough for me.
I've been using the "old school" approach of just leveraging neovim + huge list of `vimPlugins` in my Nix config, makes you about the myriad of package managers for vim/neovim.
Replacing it with nixvim is on my forever growing todo list.
Haven't moved since, Plug still does the job, even after I moved to neovim in 2021. Will probably move to the new built-in package manager once the dust has settled.
+1. Configured my plugins years ago and have not cared about the mechanism at all. I might even have confused things and landed on two. Whatever. The result is what matters: I have extensions.
In the exceedingly-rare event I do want to add one... overwhelmed with choice. "Have to" is entirely self-imposed
Me too. I don’t understand why people think they need plugin managers. I just git clone the plugin into blah/blah/start and if I feel like updating one I do a git pull.
I have been staying on vim-plug where everyone seems to be moving on to lazy.vim. I was considering a weekend to migrate to lazy.vim sometime. But with this news, I might just have to wait for this plugin manager to drop.
Why? I’ve been using dein since it was released and haven’t needed to switch to anything (though I’ve noticed the momentum shifts quickly between different ones).
Similar here too. I'm on the lazy.nvim train too because it's componentized, powerful, and scalable. It would take me ages to get all of the stuff going that Just Works™ (pretty much) OOTB. Yes, even Copilot if you're into that sort of kinky code completion sharing with OpenAI/Microsoft everything you type.
It was worth it to me because I never relied on many features of lazy.nvim. The benefit of the approach linked in the PR is that it also defer's loading packages as well. The only one I initially load is alpha.nvim (a dashboard), everything else gets deferred. This brought down my startup time from around 300ms to sub 100ms.
You're using an editor that is built to be configurable for people who enjoy endless configuration. This will not be the last config manager. You might as well ask JS community if Nextjs is the last JS framework
I have had zero issues thus far, also don't use too many plugins (like 50ish). It was way easier than expected, also had help from another person making the plugins load similarly to "lazy" as well. This setup is way way way faster than using lazy.nvim IME, especially my work computer where it would take 300 ms to load. Now it's around 80ms.
My bad, updated the links now. Reason for the passion is that I originally found out about neovim on hackernews where someone shared their dotfiles setup that used vim-plug with neovim. It looked simple to transition and I did.
Every time I see a something with the ability to import code from Git, especially if they allow specifying a branch (this pack even supports commit hashes), I wish they would document (and that more people would know) that they can "checkout" a branch at a specific time; because a lot of branches (vim plugins included) don't even bother with versioning.
ex: you can use this to checkout a repo @ a specific datetime:
> git checkout 'master@{2025-05-26 18:30:00}'
just doing my share to help people steer away from another leftPad disaster (or the xz apocalypse that almost was...)
Seems like a plausible idea but working with clocks my first question would be "whose clock is it". Is it repository defined clock? My clock? Git remote’s clock?
AFAIK this can be used for hashes, but friends don’t let friends use clocks in software developments (unless it’s last resort).
A plugin can spawn arbitrary processes so if neovim is not started in a sandbox (container, namespace, firejail...) they can basically do whatever your user has the right to do.
neovim (vim) plugins can make web requests, so you could steal secrets from a .env file being edited by, for example, making a LSP plugin active for .env files? According to my limited knowledge of LSP and how neovim plugins work, it should be possible
Could also just phone home everything a user edits using the text editor I bet.
Can someone tell me, when someone has a terminal buffer, using a vim plugin, could you potentially steal their root password when a user runs a sudo command?
And following up, could you, using that password, allow SSH connections and open ports in other system config files? Disable firewall? And potentially execute other commands using `:!` ?
I thought that gives master as of your pull time, not nearest commit to that time, which seems very confusing (it isn’t reproducible, except for yourself). I think you need a more complicated git log —before=time for any semblance of reproducibility
but thought I found a shortcut - which turns out is not really one, and like you said: confusing.
I can't edit my post, but in any case; the point being: it would be nice if import statements are closer to "github.com/google/uuid@YYYY-MM-DD" or in this case you can pass a date to version: "YYYY-MM-DD" and the library would run the uglier nested command above to import the proper version.
You don’t really need a Vim plugin manager, especially if you use git for your dotfiles.
Installing a plugin merely requires placing its files (eg: cloning its repository) into a well-known location. You can just do that.
If you track your config with git, you can track plugins with submodules. This has the added advantage of pinning the exact version (and tracking that version in for).
> If you track your config with git, you can track plugins with submodules. This has the added advantage of pinning the exact version (and tracking that version in for).
I did this for a year or so, with the motivation that submodules could replace all tool-specific package managers (for vim, tmux, zsh, etc.).
But honestly managing Git submodules felt like a chore compared to my old `vim-plug` setup. Basically because submodules are a neat concept but not implemented very ergonomically in Git. Eventually I just went back.
If someone has a setup using built-in vim pack that feels more ergonomic than vim-plug et al. then I’m very interested to hear.
I find myself enabling and disabling some plugins frequently and find it easy via the com config than the shell/filesystem . However, more importantly plugins can be activated easily based on file-type. Most plugin managers are anyway only a small wrapper around git, I guess.
Still primitive. But I'd love to drop lazy for this once they implement a differed load.
I love lazy.nvim. It's great no doubt. But recently I felt like the author is taking an aggressive user retention behavior by re-imprementing every useful open-source community plugins out there (like snack.nvim, mini.nvim). That's a kill-zone/copycat strategy. I don't get it.
I think he's pretty well placed to implent good interfaces following his paradigm, noticeably different than some other authors. I like it, so I often think his take is the best.
Snacks picker is now the best picker, for example.
I'm a long time vim user, but neovim with plugins is just not worth it for me. Something always breaks. I think neovim would do better if they started integrating the core plugins like LSP, tree sitter
> I think neovim would do better if they started integrating the core plugins like LSP, tree sitter
That's exactly what they're doing.
Both tree-sitter and LSP are built in and the primary LSP/tree-sitter plugins only bundle default LSP configurations and tree-sitter queries respectively. They're also planning to include tree-sitter query bundling into Neovim natively somehow, to make it even less reliant on the nvim-treesitter plugin.
They recently simplified the LSP configuration and to configure a new LSP you basically do this:
I was the same and kept using vim for C/C++ development. vim-plug, gutentags (ctags manager), ALE did their job pretty well and I didn't bother to learn another way.
All that changed with web dev where you have to juggle with different syntaxes and tools... I decided I would just use a neovim distribution. I have tried many but Lunarvim (now inactive) and now Astronvim have served me well so far.
I build neovim from source by myself, and maintain plugins as git submodules in pack/plugins/start (nvim automatically loads these at startup) and pack/plugins/opt (these are loaded manually) by myself. I have stuff like emmet, diffview.nvim, nvim-dap, etc loaded optionally when I want to use them. Status bar, LSP, Treesitter, and a few small tpope plugins are loaded on startup. I have a 500 line init.vim. I have a few local patches for some of the plugins.
This way, _nothing_ changes ever. That's how I want it.
I used to use astro.nvim (a few years back), then at one point I upgraded it and they had changed all the keybinds (even for basic shit like go to references IIRC), it was absolutely insane. I lost my shit and deleted the whole thing and moved to this setup. I will never use an nvim distro or update nvim plugins ever again. If I really want something I will git pull it myself (I'm looking out for nvim 12's ghost text feature for example). But in the general case, I'm done with any changes whatsoever. Not one byte.
I actually open-sourced my "approach" and documented it but I left it midway, if others are interested I might stop procrastinating and actually finish it.
I like the approach! I'd be interested in reading more. I might not fully adopt it but I m on a similar wavelength about stability. I don't want things to change unexpectedly, I just want my tools to just work consistently without surprises.
I'm quite a fan of the nvim-neorocks plugin best practices as well[2]. In fact it seems like part of them got merged recently[3] hahaha.
[1] https://neovim.io/doc/user/lua-plugin.html#lua-plugin-lazy
[2] https://github.com/nvim-neorocks/nvim-best-practices
[3] https://github.com/neovim/neovim/pull/29073
Lazy loading is much easier with Vim’s model of configuring by setting variables. You just set variables in init.vim, and the plugin can auto-load when one of its functions is executed.
With lua this requires more orchestration; if many autocmd refer to the same plugin, they all need to explicitly remember to call setup().
Edit: The Neovim setup antipattern is the Lua equivalent of writing Vimscript functions in autoload and asking users to call them in their configs instead of doing so automatically.
Deleted Comment
I currently have a Packer config on one machine and Lazy on another and honestly don't know why I bothered switching to Lazy. What I really crave is simplicity so if NeoVim builds every thing in I think it will be good enough for me.
Replacing it with nixvim is on my forever growing todo list.
- pathogen in 2011
- vundle in 2013
- vim-plug in 2017
Haven't moved since, Plug still does the job, even after I moved to neovim in 2021. Will probably move to the new built-in package manager once the dust has settled.
In the exceedingly-rare event I do want to add one... overwhelmed with choice. "Have to" is entirely self-imposed
https://github.com/azemetre/dotfiles/pull/61/files
It was worth it to me because I never relied on many features of lazy.nvim. The benefit of the approach linked in the PR is that it also defer's loading packages as well. The only one I initially load is alpha.nvim (a dashboard), everything else gets deferred. This brought down my startup time from around 300ms to sub 100ms.
https://github.com/azemetre/dotfiles/pull/61/files
I have had zero issues thus far, also don't use too many plugins (like 50ish). It was way easier than expected, also had help from another person making the plugins load similarly to "lazy" as well. This setup is way way way faster than using lazy.nvim IME, especially my work computer where it would take 300 ms to load. Now it's around 80ms.
Just trying to share the love.
Dead Comment
ex: you can use this to checkout a repo @ a specific datetime: > git checkout 'master@{2025-05-26 18:30:00}'
just doing my share to help people steer away from another leftPad disaster (or the xz apocalypse that almost was...)
AFAIK this can be used for hashes, but friends don’t let friends use clocks in software developments (unless it’s last resort).
Pretty big supply chain risks here.
Could also just phone home everything a user edits using the text editor I bet.
Can someone tell me, when someone has a terminal buffer, using a vim plugin, could you potentially steal their root password when a user runs a sudo command?
And following up, could you, using that password, allow SSH connections and open ports in other system config files? Disable firewall? And potentially execute other commands using `:!` ?
> git checkout $(git rev-list -1 --before="YYYY-MM-DD" master)
but thought I found a shortcut - which turns out is not really one, and like you said: confusing.
I can't edit my post, but in any case; the point being: it would be nice if import statements are closer to "github.com/google/uuid@YYYY-MM-DD" or in this case you can pass a date to version: "YYYY-MM-DD" and the library would run the uglier nested command above to import the proper version.
Installing a plugin merely requires placing its files (eg: cloning its repository) into a well-known location. You can just do that.
If you track your config with git, you can track plugins with submodules. This has the added advantage of pinning the exact version (and tracking that version in for).
I did this for a year or so, with the motivation that submodules could replace all tool-specific package managers (for vim, tmux, zsh, etc.).
But honestly managing Git submodules felt like a chore compared to my old `vim-plug` setup. Basically because submodules are a neat concept but not implemented very ergonomically in Git. Eventually I just went back.
If someone has a setup using built-in vim pack that feels more ergonomic than vim-plug et al. then I’m very interested to hear.
I love lazy.nvim. It's great no doubt. But recently I felt like the author is taking an aggressive user retention behavior by re-imprementing every useful open-source community plugins out there (like snack.nvim, mini.nvim). That's a kill-zone/copycat strategy. I don't get it.
// mini.nvim is a completely different author though and doesn't have to do much with lazy
https://github.com/neovim/neovim/pulls?q=is%3Apr+pack+is%3Ac...
Snacks picker is now the best picker, for example.
That's exactly what they're doing.
Both tree-sitter and LSP are built in and the primary LSP/tree-sitter plugins only bundle default LSP configurations and tree-sitter queries respectively. They're also planning to include tree-sitter query bundling into Neovim natively somehow, to make it even less reliant on the nvim-treesitter plugin.
They recently simplified the LSP configuration and to configure a new LSP you basically do this:
And then in the "LspAttach" autocmd you can define your LSP specific keymaps for example.If you want. It also now ships with most auto-mapped.
All that changed with web dev where you have to juggle with different syntaxes and tools... I decided I would just use a neovim distribution. I have tried many but Lunarvim (now inactive) and now Astronvim have served me well so far.
Deleted Comment
This way, _nothing_ changes ever. That's how I want it.
I used to use astro.nvim (a few years back), then at one point I upgraded it and they had changed all the keybinds (even for basic shit like go to references IIRC), it was absolutely insane. I lost my shit and deleted the whole thing and moved to this setup. I will never use an nvim distro or update nvim plugins ever again. If I really want something I will git pull it myself (I'm looking out for nvim 12's ghost text feature for example). But in the general case, I'm done with any changes whatsoever. Not one byte.
I actually open-sourced my "approach" and documented it but I left it midway, if others are interested I might stop procrastinating and actually finish it.