- Published on
A Soy Dev Guide to Neovim
- Authors
- Name
- Duy Nguyen
- @duy_the_dev
Introduction
Hold on to your soy lattes because we are about to go on an ascension journey from a mere VSCode normie to "I use vim btw" Chadhood. I promise by the end of this guide, you will go from a soy dev to a soy dev with a neckbeard. You will go from pushing buggy JavaScript code, to pushing buggy JavaScript code blazingly fast.
This guide will be broken up into two separate sections:
- The first section will cover the basics, installation of Neovim, LazyVim, and how to customize LazyVim's default plugins and configuration. Readers interested in setting up their own configurations is encouraged to stop here and explore LazyVim's documentation.
- At the end, I will provide my personal configuration files as reference for those who are interested in a more opinionated setup.
- Pre-Requisites
- Backup Your Configurations (Optional)
- Neovim Installation
- LazyVim Installation
- Core Features
- Directory Explorer
- Fuzzy Finder
- LSP Support
- Syntax Highlighting
- Git Integration
- Customizing Default Configurations
- Configuration Files
- Override Default Configurations
- Override Default Plugins
- Adding New Plugins
- Disabling Default Plugins
- Summary
- My Configurations
Pre-Requisites
- Basic knowledge of Vim motions and commands.
- Homebrew for package management
- A working internet connection
Backup Your Configurations (Optional)
If you have an existing nvim configuration, it is recommended to back it up before proceeding.
mv ~/.config/nvim ~/.config/nvim.bak
mv ~/.local/share/nvim ~/.local/share/nvim.bak
Neovim Installation
The official neovim github repo lists the installation instructions for various platforms. For most users, installing neovim via a package manager is the easiest way to get started. I personally use homebrew as I work mainly on MacOS and Linux.
brew install neovim
After installation, you can start neovim by running nvim
.

LazyVim Installation
LazyVim is a Neovim setup, powered by lazy.nvim. It comes with a set of very useful plugins and configuration that are designed to work out of the box. The user experience is very similar to VSCode, with features like LSP support, syntax highlighting, and fuzzy finder.
Before we continue, it is important to understand that in its default state, Neovim is no different than its older brother, Vim. The secret sauce behind Neovim's powerful features lies within the support for plugins, open source projects developed and mainted by the nvim
community. With the help of these plugins, we can extend Neovim's functionality to our liking. LazyVim is simply a curated set of neatly packaged plugins. Even the plugin manager, lazy.nvim
, is itself a plugin.
This means that we have full control over our Neovim configurations, even with LazyVim installed. We can add, remove, or modify any of the plugins or configurations to our liking. The lazy.nvim
plugin manager is designed to make this process as easy as possible.
Install Optional Dependencies
Some of LazyVim
pre-configured plugins require additional dependencies to be installed. They are optional, but highly recommended.
brew install ripgrep fd
Clone LazyVim Starter Template
git clone https://github.com/LazyVim/starter ~/.config/nvim
cd ~/.config/nvim
Remove the .git
Directory
We will remove the .git
directory so that you can track your own configurations in a separate git repository.
rm -rf .git
Start neovim by running nvim
.
nvim
You will be greeted with LazyVim's initial setup screen.

Neovim will automatically install the required plugins and set up the configurations. Once the setup is complete, we should see the tokyonight
theme applied.

Hitting q
will close the prompt and open the dashboard.

Initialize Git
Finally, let's initialize git
in our configuration directory before playing around with the configurations.
git init
git add .
git commit -m "init LazyVim"
Core Features
Besides having all the basic vim motions and functionalities, LazyVim comes with a set of features that are designed to make your life easier as a developer. In this section we will cover some of the most useful features, and in the following section we will learn how to customize them.
For a list of all available default plugins, visit LazyVim's website
Directory Explorer
File tree explorer is managed by neo-tree.nvim
. To open the directory explorer, hit <leader>+e
. By default, the <leader>
key is mapped to the space bar.

Common neo-tree
key bindings:
j
andk
to navigate up and downl
orEnter
to open a file or directoryh
to collapse a directoryr
to rename a file or directoryd
to delete a file or directorya
to add a new file (or a new directory by adding the/
suffix)?
to open the help menu and view all available key bindings
Fuzzy Finder
Fuzzy finding functionalities are provided by telescope.nvim
. Telescope relies on ripgrep rg
and fd
to expose a set of commands that allow you to search for files, buffers, and more, in a neat modal UI. To open the fuzzy finder, hit <leader>+f
(as in "find") or <leader>+s
(as in "search"). The which-key
plugin is also installed by default, which will show you all available key bindings.

Common telescope
key bindings:
<leader>+ff
to find files<leader>+fb
to find buffers<leader>+fr
to find recently opened files<leader>+sw
to search the current word under the cursor in the current working directory<leader>+sg
to search for a string in the current working directory (live grep)<leader>+st
to search for all @todo
LSP Support
LSP support is provided by a combination of different plugins, which requires its own plugin manager, mason.nvim
. We could learn more about mason.nvim
and how LSP works, but our soy lattes are getting cold so LazyVim comes with a pre-configured LSP setup that works out of the box. You can open the LSP menu by using the command :LazyExtras
. Would you look at that, lang.typescript
is right there in the Recommended Languages section. Let's install it by hitting x
on the keyboard.

Now, if we open a ts
file, we should see the LSP features in action. For example, we can see the type of the variable under the cursor by hitting K
in normal mode. Or use the g+d
key binding to jump to the definition of a symbol. As we can see below, hitting K
reveals the function signature of the BentoChildContainer
component.

If you're interested, you can see which LSP servers are currently attached to your buffer by using the :LspInfo
command.

Syntax Highlighting
Syntax highlighting, indentation, and folding are all supported by nvim-treesitter
. I'll be completely honest here, I'm not smart enough to understand how it works so I'll just defer you to the official documentation. But hey, it works out of the box and that's all that matters. nvim-treesitter
exposes a set of vim commands prefixed with TS
, for example, TSToggle
to toggle treesitter on and off. I wonder if we can use them for anything useful.
Git Integration
Almost all core plugins in LazyVim have git integration. For example, in the directory explorer, we can see the git status of each file. We can also filter files by their git status or jump back and forth between them. In the fuzzy finder, we can search for files based on their git status. Most importantly, lazygit
gives us a terminal git UI that we can use to stage, commit, and push changes, lazygit
also provides us with more advanced capabilities such as viewing diffs and resolve merge conflicts, see commit history, and more. You can open lazygit
by pressing <leader>+gg
.

Hitting ?
wil bring up the help menu and display all available key bindings, based on the current menu context.
Customizing Default Configurations
Configuration Files
Our config and plugins are managed by lazy.nvim
. This guide only scratch the surface of what lazy.nvim
has to offer. I implore curious on-lookers to peruse the official documentation.
If we change directory into ~/.config/nvim
, we will see the following structure:
~/.config/nvim
├── lua
│ ├── config
│ │ ├── autocmds.lua
│ │ ├── keymaps.lua
│ │ ├── lazy.lua
│ │ └── options.lua
│ └── plugins
│ ├── example.lua
└── init.lua
IMPORTANT!!!: Do not require autocmds, keymaps, lazy
or options
under lua/config/
or lazyvim.config
manually. LazyVim will load those files automatically.
Override Default Configurations
While LazyVim does come with a set of default configurations, we can override them by editing the files in ./config
as they will be loaded after the default configurations. For example, LazyVim's default scrolloff
is 4 lines. I prefer 8 lines, so I can override it by adding the following line to ./config/options.lua
.
-- Options are automatically loaded before lazy.nvim startup
-- Default options that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/options.lua
-- Add any additional options here
+
+ vim.opt.scrolloff = 8
Similarly, we can update the default vim keybindings like so:
-- Keymaps are automatically loaded on the VeryLazy event
-- Default keymaps that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/keymaps.lua
-- Add any additional keymaps here
+ -- Selet all
+ vim.keymap.set("n", "<C-A>", "gg<S-v>G")
Override Default Plugins
Finally, we can inject custom configuration for default plugins by adding new files to the ./lua/plugins
directory. For example, by default, neo-tree.nvim
, our directory explorer and netrw
replacement, hides filtered items such as .git
, node_modules
, or other files and directories listed in your .gitignore
.

I am not a fan of this behavior, and often ends up having to toggle this feature off every time I open a new nvim
instance. If we head over to the neo-tree.nvim
github repo, we can see that we can change this behavior by setting filtered_items.visible
to true
. Let's change that by adding a new file ./lua/plugins/neo-tree.lua
with the following content:
nvim ./lua/plugins/neo-tree.lua
+ return {
+ "nvim-neo-tree/neo-tree.nvim",
+ opts = {
+ filesystem = {
+ filtered_items = {
+ visible = true, -- show filtered items (default = false)
+ },
+ },
+ },
+ }
Adding New Plugins
We can also add new plugins not available in LazyVim by default. We can do this by adding a new file to the ./lua/plugins
directory. As an example, let's add the gruvbox.nvim
colorscheme plugin. Simply create a new file called gruvbox.lua
in the ./lua/plugins
directory with the following content:
nvim ./lua/plugins/gruvbox.lua
+ return {
+ "ellisonleao/gruvbox.nvim", -- name of the plugin (usually formatted as github <author_slug>/<repo_slug>)
+ lazy = false, -- we can lazy load any plugins we do not need right away by setting this to true
+ priority = 1000, -- as well as the loading priority
+ config = true,
+
+ -- add your config below
+ -- refer to https://github.com/ellisonleao/gruvbox.nvim
+ -- for a list of all available customization options
+ opts = {},
+ }
Then, restart Neovim and run :colorscheme gruvbox
to apply the new colorscheme. Look at all that turd brown chocolatey goodness.

Optionally, instead of just returning one plugin per file, we can return a table of plugins. This is useful when we want to group related plugins together. For example, I have a set of two or three different colorscheme I enjoy switching around every so often, instead of having multiple files for each plugin, let's create a single colorscheme.lua
inside the ./lua/plugins
directory.
return {
{
"ellisonleao/gruvbox.nvim",
lazy = true,
priority = 1000,
}
{
"cranberry-clockworks/coal.nvim",
lazy = true,
priority = 1000,
},
{
"craftzdog/solarized-osaka.nvim",
lazy = true,
priority = 1000,
opts = function()
return {
transparent = true,
}
end,
},
{
-- here we call LazyVim to load the default colorscheme we want to use on startup
"LazyVim/LazyVim",
opts = {
colorscheme = "coal",
},
},
}
Disabling Default Plugins
Finally if you wish to disale a default LazyVim plugin entirely, we can do so by setting enabled = false
. I'll use folke/flash.nvim
as an example. It is a very useful plugin, but I prefer to use the built-in /
search highlight feature. Using what we learned above, let's create a new file disabled.lua
inside the ./lua/plugins
directory, this way we can group all our disabled plugins together.
return {
{
"folke/flash.nvim",
enabled = false,
},
-- add more disabled plugins here
}
Summary
If you have been following the guide so far, you have now learned how to:
- Install Neovim and LazyVim
- Use core features
- Customize LazyVim's default configurations
Armed with this knowledge, you are ready to explore and customize your Neovim experience. Now that's a development environment with a bit more neck hair.
My Configurations
This guide is long enough as is, so I will not go into detail about my personal configurations. You can find them on my GitHub repository