I moved to Neovim and love it, but is it right for you?

I moved to Neovim and love it, but is it right for you?

·

25 min read

Let me start out by clarifying a few things so that you have a better understanding of the point of this post.

First, this won't be a sales pitch trying to get more people on the "Vim" bandwagon. I honestly don't think it's the right tool for everyone. I do think you should try it if you haven't, but I'm biased because I like it. In the end, a code editor is designed to edit code, and Vim is one of many tools that can edit code effectively. If you already have a fast and efficient workflow with another editor and you are happy with it, this post might not be helpful to you. (but you still might find it informative!) If you are curious about Vim or you feel that your current editor experience is lacking, read on.

Second, keep in mind that learning a new tool to do something you already know how to do is a chore. If you decide to try it, it will take some time to get comfortable, and it will take some time to gain proficiency. You will move slower at first, you will have greater mental overhead during the adjustment period, and you may be frustrated often. So if you do feel inspired to try Vim, or any other new tool, give it enough time to say you gave it a fair shot. And make sure your comparison is fair. If you are using VS Code for example, and if you haven't looked through all the menus and done at least a cursory read-through of the documentation, I think you should. You could be missing features that could change your whole workflow for the better.

What I would like to do here is tell you about the drivers behind my decision to try Vim in the first place, why I decided on Neovim vs Vim, and how my experience has been so far. I won't go into the "how to", but I'll provide some links later on that can help you if you are interested. The goal I have in mind is to help people make an informed decision on whether or not to try it. Nothing more, nothing less. I want to maintain a level head and provide some honesty to cut through the noise. I hope you find my experience helpful.

The Back Story - Why look at Vim in the first place?

My first real coding experience was in Visual Basic for Applications, writing custom logic for an MS Access program. I soon realized that VBA wasn't the language I was going to stick with and I wanted to learn a common enterprise language, and C# appeared to be the best bet. So I downloaded Visual Studio Community Edition, bought a Udemy course on C# and got to work. (Thanks Mosh Hamedani btw, awesome teacher!) I enjoyed the language but struggled with the IDE. Visual Studio is a BIG program, with a lot of deep integrations. It turns out, many of those integrations are just Gui skin over command line tools anyway, so I started using the CLI more to do things like run, build, add dependencies, etc.

This worked well enough for a while, but I always felt that Visual Studio was just too big. Load times were long, and it was heavy on system resources. And Visual Studio Code was on the scene by this point with extensions coming up everywhere. It looked like I could get the bulk of the functionality I used in a lighter package with quicker startup times. So I made the jump.

As time marched on, I started to get more confident and I was having a blast creating, but I hit my next stumbling block. I started to experience friction between thinking of the code I wanted to write and getting it into the editor. Refactoring and generally moving around seemed harder than they should be. I was turning my hands into crab shapes to hit Ctrl+Shift+whatever-else to use shortcuts. And I'm not a full time developer, so it takes longer to develop muscle memory on things like shortcuts just because I don't use them as much. Also, I take the chances I can get to write some code. If I hit the button to start an editor and it takes a minute or two for startup and for the language services to initialize, it bugs me, and VS Code was doing this to me. It was also still more resource heavy than I like with a half a gig of RAM usage and multiple processes hitting the CPU.

I'm not the fastest typist but I am a touch typist. Coding speed wasn't the issue, but in a flow state I found it very annoying to have to stop and try to remember a keyboard shortcut or dig back in to the shortcuts editor to find it again, or wait for some unexplained lag to stop happening so things would work. Reaching for the Ctrl, Alt, and Shift keys in strange combos with other keys just felt uncomfortable. My excitement for coding was being tempered by a growing feeling of "Is this the best I can do?" when thinking about using the editor.

I knew there had to be a better way, but I didn't know where to start. Most code editors with advanced features have similar outlooks on keybindings, and are often heavy on resources. I looked into Jetbrains products, looked briefly at Emacs, read up on Sublime a bit, and wasn't thrilled with any of them. (Though they are all great, just not for me.) And then I saw a thumbnail for a Youtube video on "Your first VimRC" and watched it over a lunch break. And I thought, "This does look different. Why not try it?"

A Brief primer on the Vim way, and Vim vs Neovim.

The first thing you need to know is that Vim is a modal editor. This means you have different modes for doing different things. Normal mode is for moving around, insert mode is for actually writing text into the editor, visual mode is for selecting words, lines, and blocks and manipulating them, and command mode is for issuing commands to Vim to do anything from searching for something to quitting the program.

The next thing you need to know is that Normal and Visual modes both depend on something called motions, which is how you move around the editor screen. Vim is designed to be used without a mouse and the motions are how this is done. There is also a huge variety of other things available, including forward and backward search, keys to scroll up and down, and so on. Vim aims to follow the Unix ethos of doing one thing and doing it well, and it's great at being text editor.

The last important thing to know is that Vim and Neovim use the same motions and actually share a lot of the same source code. Neovim is a fork of Vim and the two teams are on good terms and work together on many things. The casual user can use the same base installation of either one interchangeably. The key difference is that Vim uses a special language called VimScript as the primary extension and configuration language, whereas Neovim uses Lua. Neovim can read most VimScript as long as it doesn't use the most current features. However Neovim has embraced Lua and a full API layer from the core program that interfaces with Lua, and as a result the ecosystem for plugins has exploded with Lua development. Vim in contrast is now using a newer version of Vimscript that Neovim doesn't fully support. The result is that plugins for one won't always work on the other.

Not all babies are pretty!

When you first open a raw, unconfigured instance of Vim or Neovim, it's ..... kinda ugly. The colors are pretty harsh and there isn't much in the way of visual niceties that you might be used to seeing. I started with Vim because it was already installed and I just wanted to try it. So I fired up the included interactive tutor and started working through it. Pretty quickly I had the basics of just moving around, albeit slowly and with some thought involved. Then it was on to the included manual. There is a lot of great information that comes with the base installation and I enjoyed getting familiar with it.

Once I realized I was enjoying myself, I looked at how to start customizing things.... and hit a wall. VimScript just isn't intuitive to me. But I had already heard that Neovim used Lua, so I installed Neovim and started playing around with it, and it felt like a better fit. I knew that learning Lua would have a payoff beyond Vim as well. (A lot of common tools use Lua as a scripting language, such as Redis, HAProxy, and MySql workbench)

The first thing customizers usually do is install a package manager, and I was no exception. Then I installed a color theme, restarted the program, and things looked better right away. And I had my first config! It was only about a half dozen lines that just changed the theme, but it was a start!

Let's make VS Code in a terminal text editor!

This was my first direction. It turned out to be a mistake. I tried to copy (more or less) the experience I was used to with VS Code into a Neovim configuration.

Now, to be clear, there are "distributions" of Neovim configurations that will get you really close to a VS Code style experience by using pre-made and well-maintained configs and plugin arrangements and handling a lot of the complexity I'll get into later. These are great options if that is what you are after and you want an out-of-the-box experience. I wasn't aware of them at the time though, so I just tried to make a VSClone myself. Also, knowing what I know now, I would choose to go another direction anyway.

The way plugins work in Neovim is that you have a package manager that links to the location of a plugin and pulls the code into your local file structure if necessary. Plugins can be local directories or Github repo's of the code for the plugin. You include the plugin path in a table in a Lua file, run a command, and the package manager will download the code if needed and make sure Neovim knows where to find it. In some cases this is enough for it to work, but most of the time you still have to set up and configure the plugin so Neovim can use it. And most plugins have decent documentation on how to do that, complete with code examples in Lua. So I started adding plugins and setup code without really knowing what I was doing. (Copy / Paste are not always your friend!) I got some things working, but it quickly turned into a mess that I couldn't fully understand. Some plugins were overwriting configs for others, keymaps were everywhere, and it was ugly.

Out of frustration, I deleted it all and started again. But I learned an important lesson, and this is probably the biggest takeaway from this post. If I was happy with my coding experience in VS Code, why was I looking at other options? And why was I trying to turn those other options into VS Code? By extension, if you are happy and productive with your experience in any code editor or IDE, why leave? A tool only makes you a better developer if it is solving a problem for you, and if you don't have any problems that need solving, your time and energy might be better spent by focusing less on the tools and more on the code itself. If something is working, maybe ignore the FOMO and work on other things instead.

I wasn't happy in VS Code though. In fact, that sense of unease and that sense of friction I mentioned earlier were really nagging at me, to the point that I wasn't enjoying writing code. But what I'd cobbled together as my first attempt at a Neovim config wasn't making me happy either. Once I thought about that, I realized it was foolish to try and copy VS Code, because Vim in general is a very different tool than VS Code, and I needed to look at it differently. So I came up with another approach.

Personal Development Environment

Before I started hacking another config together in Neovim, I took a moment to reflect on what I had learned so far. And I came to a realization of just how much a tool like VS Code is doing for the users that they never actually see. It's easy to find an extension to do something like formatting or adding support for a new language, and then just install it and maybe change something in a menu and it works. There is a huge burden of compatibility and stability that falls to the extension authors, and the users get the benefit at the cost of configurability. Neovim doesn't have that, though the plugin authors work hard to make sure things stay working. When you install a plugin, you also need to write the related setup code (or copy it from the docs) and then you need to verify that it's working as intended. It's also probably a good idea to look through the source code of any extensions and make sure they aren't doing anything shady. (though I haven't found a single bad apple yet)

Keeping these thoughts in mind, and knowing I had to own my own configuration and handle it responsibly, I decided that I would start using basic Neovim with a color theme installed, and just start working with some code. Whenever I came across something that was causing friction, I would research how to change it or approach the problem differently, and only install a plugin if it was appropriate to do so. I would also take the time to understand what the plugin was giving me, what setup options were available, and how it would interact with other plugins I already had set up. Off I went!

And then things started to get interesting.

The Neovim community talks about the idea of a "Personalized Development Environment" and even though I had heard it before, I didn't fully understand what it meant until I started carefully building up my own setup from my new, more strict philosophy. I also think there was a good deal of value in failing to set it up once, because I was more aware of what not to do. I found that the key idea is that I can add and change functionality to fit my needs, in any way that I see fit, for better or for worse. And by letting go of all of the conventions I had learned through 2 other editors, I was able to focus on what I needed an editor to do and not how to bend my needs to fit the model of the editor. As a result of this process, I don't have a huge list of plugins and each one has a purpose. Some of the highlights are as follows:

  • File navigation the slow way - Most IDE's have a file tree in a window on the side of the editor that people use to navigate files. Out of the box, Vim has something called NetRW which is a simple version of this with several other capabilities built in. When you open it, it takes up the whole screen by default, and when you pick a file, it goes away and the file you picked takes up the screen in its place. It's a simple tool that does the basics of file navigation well enough. As a result, I didn't need to add a file tree plugin at all. (though there are many!) NetRW does its job, and I have a plugin that makes it look nicer with things like file-type icons, but there are other ways to move around in projects as well.

  • File Navigation the fast way - Most IDE's also have the concept of a fuzzy finder to get to files. Once you have an idea of the file structure of a project, using the fuzzy finder is helpful to move around much faster. Now imagine that your fuzzy finder allows you to bring up a list of files, and as you scroll through them you see a preview of the highlighted file in a window off to the side. And what if the same fuzzy finder could be used to find keymaps, help documents, and even search for a term inside files and allow you to jump right into the file at the location of the search term? This is all easy to do with the Telescope plugin. And Telescope will allow you to search through any source that can generate a list. Not all at once mind you, that would be too chaotic. But it's the same interface for searching different things, and you use a "picker" to access each type of search. The list of things you can search through with the built-in pickers is pretty insane, and then you can write extensions for it to add more pickers. There is even a built-in picker for searching through built-in pickers. And it all runs really, REALLY fast. As a result, the bulk of my file navigation is now done through Telescope, along with searching help docs, finding open "buffers" (analogous to tabs in other editors), etc.

  • Snippets on steroids - Most people who write code are familiar with the idea of code snippets, and they are very useful. And of course, Neovim has multiple plugins that allow you to use them. You can even use these plugins to load snippets in both the VS Code and Snipmate styles and use them as is. (You might need to install a regex tool for some advanced transforms though) This allows you to use snippets collections from VS Code plugins and a wide variety of other sources. However, someone thought that wasn't enough and wrote the Luasnip plugin. It can load snippets from other sources like I just mentioned, but also has a programmatic API that allows you to build extremely complex and performant snippets with code. You can use snippets inside snippets, and have one part of a snippet fill in based on a calculation from another part, do code transforms, conditional jump points, etc. The end result is a huge amount of power and control, limited only by your imagination. I've barely scratched the surface of this one and I already love it.

  • A better way to map keys - In Vim, keys are done in sequence for pretty much everything. You still have access to the Ctrl key, but only with one other key at a time. Instead of mapping actions to a number of keys pressed at the same time, you map things to trigger after a sequence of keys is pressed. There are a number of sensible maps that come standard, like "ciw" which maps to "Change inside word" and will delete the word your cursor is on and change to insert mode so you can enter something different. You can remap any of the basic keymaps as well. However, you also have a "Leader" key that you can set to any key you want. (I use the space bar.) The leader allows you to move to a user-defined keymap palette and specify key sequences to do whatever you can dream up, without interfering with the built-in mappings. So I have mine arranged in groups. Leader key, then "f" for finding things, "g" for going places, "c" for changing things, etc. By typing Leader-f-f in normal mode, I open my file finder, and Leader-s-v splits the window vertically. It becomes much easier to use keymaps because I rarely have to reach for the control key, and mappings are in logical sequences making them easier to remember. But what if I don't remember them?

  • Everything is discoverable - You can find anything from within the program, starting with keymaps. I have a plugin called Which-Key that works as follows. Say you start a sequence for a key mapping and forget where you are going. After a short delay, a window pops up along the bottom of your screen that tells you where you can go next based on what you already entered for mappings. So if you forget something, it prompts you along to the result you need. But what about when you forget how to start the sequence? I also have a keymap set up that opens the Telescope plugin that allows me to search through keymaps in the same search tool I use for everything else. What if I flat-out forgot how to use a plugin? Telescope again allows me to fuzzy search help topics, and nearly all plugins ship with documentation in a formatted text file that you can jump around in, almost like HTML in the terminal. The result is that I can find things with less effort and thought than I ever could in VS Code. It helps me to become a more proficient user faster with less effort involved.

These are just a few of the things I've discovered as I've built the configuration I'm using now. I have tools to do advanced find and replace using Regex captures (Native to Vim - not a plugin!), key maps to move lines or blocks of code up or down, etc. I also understand what everything I'm using is giving me, and how the pieces fit together. This means if I find anything that is bugging me, I can go in and fix it. This is true from keymaps to functionality to window layouts. I have control over my editing environment now, and that makes it personal and functional to me.

It's also really fast and light on resources. Since Vim in general is a terminal-based program, everything is done through text representation and the use of Nerd fonts for symbols and the like. No GUI rendering overhead. I can navigate to a project directory, hit the command to open Neovim, and it's ready to use in less than a second. (and I haven't even started optimizing yet!) And since it's all done using code to configure, I can keep my config under version control, push it to github to back it up, branch it to try new things with no fear of breaking a working config, etc. So on top of the speed and the personalization, I have the freedom to experiment. It's all very liberating.

But like anything in life, the good comes with the bad. And there are some things you might find challenging that we need to discuss also.

The hard parts

The first thing to mention is that Vim is stable and is at version 9.0 as of the time this was written. Neovim is not yet at version 1.0. As of the date of this post, Neovim is at version 0.8 with a nightly dev build of version 0.9 available, and since it's in beta status there are still several things in the API that are changing. Furthermore, many OS package managers are shipping an earlier version, so if you want to be up to date with the latest and greatest, you will need to download and build from source code or download an app image and configure it to run as a binary. If you aren't comfortable with doing that, Neovim might not be the tool for you. (though there are many guides floating around to do this.)

Next, the whole ecosystem is moving very fast. It's not uncommon for plugin authors to add a ton of updates and maybe introduce breaking changes in a very short amount of time. It's also very easy to forget that fact, and then ask your package manager to update all plugins while installing a new one, and suddenly something else stops working and you have to debug it. General rule of thumb: If you have a working Neovim config, leave it alone and go write some code.

Also missing are some of the deep language integrations that you can get from full blown IDE's that will allow large-scale intelligent refactoring and code suggestions. If you are using features like this in IntelliJ, Visual Studio, or other IDE's and you count on them, you may miss them in Neovim. And if you are a full-time Java or C# dev, you might struggle to get what you are used to from Neovim in its current state.

If you want to use Neovim to its fullest, you will also likely need to learn Lua. It's a nice little language with some quirks, but it's generally easy to get up to speed and it's not a complex language to use. It's still another thing you have to learn though, as nearly all of the plugins will require some setup code to integrate with Neovim itself and that code will be Lua. You can also use the Lua API in Neovim to do things like keymaps, editor commands, set core config options, and a whole host of other things. So it's worth the time to learn if you want to use the tools. However, if you aren't yet comfortable with coding concepts like abstraction and modularity or if you are still learning to code in the first place, working with Lua and all the API's can get overwhelming very fast. See the next section for some options that might suit you better.

Speaking of setting things up, you will have to do a lot more of it on your own. Things like language servers will need to be set up, along with the adapters to make Neovim talk to them, and a completion engine for Intellisense and snippets, and plugins that allow the language servers to act as sources for the completion engine. And of course a range of plugins that allow these things to integrate into your configuration in a variety of different ways. There are some things that handle parts of all this setup for you, at the cost of your own ability to customize as needed. There are also plugins that offer sane defaults you can start from and then change things as needed. Conceptually though, you will see under the hood of what a lot of IDE's are doing on your behalf.

If you aren't someone who likes to tinker and tweak, Vim may not be a good fit also. Something that is commonly mentioned in the Vim community is that your personal configuration is an ever-evolving project on its own. You will find yourself adjusting, adding, refactoring, and trying new things all the time. If you aren't that type of personality, you might not have a good time. Note that you can leave it as the stock installation and not configure it and it will still edit text, but a lot of the really nice additions either won't be there or will be harder to reach, like LSP for example.

Also, if you aren't comfortable working with the command line, Vim probably isn't right for you either. You'll be spending a lot of time in a terminal by design.

And some things are just plain painful to work with. Setting up Javascript and Typescript debuggers was one of my pain points. I have a Node debugger that is currently working, but it's using a deprecated adapter. Sooner or later I'll have to figure out how to get the current adapter working.

So keep in mind that there are tradeoffs to everything, and you have to be willing to take the bad with the good. In a lot of cases, the convenience and stability of other IDE's might be right for you.

Is there a middle ground?

Yes there is. Actually there are a few approaches to meeting in the middle, and any of them might be good for you.

First, most IDE's have a way to set up Vim keybindings so you can start using the motions. And for what it's worth, the motions are actually pretty good. You can research that option for your IDE of choice and still keep the rest of your workflow intact.

In the case of VS Code, it goes a step further. With the VSCode Neovim plugin, you can use a fully featured Neovim instance embedded inside VS Code, including Neovim plugins. This gives you the best of both worlds, but you will still have the runtime and rendering overhead of VS Code itself. Still, many people are very happy with it.

If you want to go full-on Neovim but want a more or less ready-to-use experience, you can check out AstroNvim, LunarVim and NvChad. All three of these are well-loved in the community and can work as-is for an excellent experience, or be customized and extended to meet your needs. There are some others out there as well, but these three names come up all the time. (Quick note on this though, by using these you are abstracting what the configuration is doing, so it might actually be harder to start understanding and customizing your own config)

If you want a jumping-off point to build a config yourself, you can start with Kickstart.nvim which is a basic configuration with some niceties included and is designed to be built on top of. TJ Devries also made a great Youtube video walking through setting it up and using it for the first time.

And if you want to start from scratch and build your own configuration, you can't go wrong with the Youtube tutorial by ThePrimeagen that walks you through how to do it from the ground up.

Also, if you are looking at Neovim, you should also look at straight-up Vim, which is mature and very stable. The base, unconfigured installation is virtually identical to Neovim in how you use it, and does come pre-installed on many systems. The range of plugins is also quite large and most are very stable themselves, and Vimscript might be a better configuration language for you.

Lastly, I would be doing you a great disservice if I didn't tell you about Helix, which is a modal editor that works in slightly different style than Vim. From what I've seen around the internet, it's really good already and it's still in early development. If you are looking at Vim, you'd better look at Helix also. I've only done a cursory look at Helix myself, so I can't provide much more, and that would be outside the scope of this post anyway.

And if you are Vim-curious and need some help, there are resources sprinkled around the internet, Reddit groups, discord channels, and Neovim also has an IRC channel that you can join if you want. The people you will come across are passionate about the tools they use and will genuinely want to help. Neovim also has Neovimcraft which is a site dedicated to plugin discovery. However you seek help though, don't be surprised if the answer you get is a pointer to the built-in docs. They are extensive and useful, and constantly getting better. Both the Vim and Neovim communities want them to be the included and relied upon source of truth.

So, is Neovim right for you?

I can't answer this question for you. What I can do is encourage you to keep an open mind and ask if you are getting what you need from whatever tools you are using. I can also ask you to do a deep dive on all of your existing tools and figure out what you might not be using that could be helpful. You might be surprised at what you discover.

From my perspective, I'm enjoying writing code again. It took a lot of work and a lot of learning though. I have a much better appreciation of the time and energy that goes into any modern code editor. There are a lot of brilliant people out there that are making awesome tools for all of us to use. (You might even be one of them! Thank you if you are!) Using and configuring Neovim gave me a window into that work that I hadn't seen before. Switching over was the right thing - FOR ME! That doesn't make it right for anyone else.

So however you go about doing it, I hope that your coding experience is something you enjoy. Hopefully I've also inspired you to experiment and find the best workflow and tools for you. Make it yours, play around with it, and have fun, regardless of what you are using.

Thanks for reading, and please feel welcome to leave a comment on your own experience. I'd love to hear about it.

Special note: The terminal background image I used in the cover image is a beautiful photo from Jaanus Jagomägi on Unsplash, with a semi-transparent layer placed on top to darken it. Thank you Jaanus for capturing and sharing that photo!