my neovim setup in 2026
I’ve been using Neovim as my main editor for about two years now. Every few months I re-evaluate the config, drop things I don’t use, and occasionally add something new. Here’s where it’s at right now.
The basics
I keep my config in ~/.config/nvim/ and manage plugins with lazy.nvim. The full config is ~400 lines across a few files, nothing crazy.
-- lazy.nvim bootstrap
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
vim.fn.system({
"git", "clone", "--filter=blob:none",
"https://github.com/folke/lazy.nvim.git",
"--branch=stable", lazypath,
})
end
vim.opt.rtp:prepend(lazypath)
Plugin list
Here’s what I currently have installed:
| Plugin | What it does |
|---|---|
| telescope.nvim | fuzzy finder for files, grep, buffers |
| treesitter | syntax highlighting, text objects |
| lspconfig | LSP setup for TS, Go, Rust |
| oil.nvim | file explorer that feels like a buffer |
| mini.surround | surround text objects |
| gitsigns | git diff in the gutter |
I used to have a lot more: nvim-tree, bufferline, lualine with a fancy config. Dropped all of it. The less UI chrome, the better.
Keybinds that matter
Most of my keybinds are leader-based. I use space as leader.
vim.g.mapleader = " "
-- files
vim.keymap.set("n", "<leader>ff", "<cmd>Telescope find_files<cr>")
vim.keymap.set("n", "<leader>fg", "<cmd>Telescope live_grep<cr>")
vim.keymap.set("n", "<leader>fb", "<cmd>Telescope buffers<cr>")
-- lsp
vim.keymap.set("n", "gd", vim.lsp.buf.definition)
vim.keymap.set("n", "K", vim.lsp.buf.hover)
vim.keymap.set("n", "<leader>rn", vim.lsp.buf.rename)
vim.keymap.set("n", "<leader>ca", vim.lsp.buf.code_action)
The thing about keybinds is that you should only map things you actually use. I see configs with 100+ mappings and I guarantee half of them are forgotten within a week.
Screenshot
Here’s what it looks like in practice, editing a TypeScript file with the gruvbox colorscheme:
LSP config
For TypeScript I use ts_ls, for Go gopls, for Rust rust-analyzer. The config is minimal:
local lspconfig = require("lspconfig")
local servers = { "ts_ls", "gopls", "rust_analyzer" }
for _, server in ipairs(servers) do
lspconfig[server].setup({
capabilities = require("cmp_nvim_lsp").default_capabilities(),
})
end
No fancy wrappers. If the LSP supports it, Neovim handles it. Format on save is just an autocommand:
vim.api.nvim_create_autocmd("BufWritePre", {
callback = function()
vim.lsp.buf.format({ async = false })
end,
})
What I’d change
Honestly not much right now. The config is stable. The one thing I keep going back and forth on is whether to use conform.nvim for formatting instead of the built-in LSP formatter. For now the built-in is good enough.
If you want to check the full config, it’s in my dotfiles repo.