NvChad: The Complete Guide to Shortcuts, Commands, and Daily Workflow
Learn NvChad from scratch: installation, core keymaps, Telescope, LSP, custom plugins, and how to update and extend NvChad without breaking anything.
Most developers who try Neovim get stuck in the same place: they spend days configuring options, trying plugins, debugging init.lua, and never actually writing code. NvChad solves that problem by giving you a full, carefully curated Neovim setup on day one β a file tree, statusline, Telescope fuzzy finder, LSP support, Treesitter highlighting, and a clean theme β all wired together and ready to use.
Think of NvChad as the difference between buying furniture and building it yourself. Both end in a functional room, but one gets you working immediately while the other is a months-long weekend project. NvChad is the assembled furniture. The point is not that you cannot configure Neovim from scratch β it is that you probably should not until you understand what you need.
This guide covers NvChad specifically β not vanilla Neovim configuration. By the end you will know every important keymap, how the customization system works, how to add plugins and LSP servers, and how to keep everything up to date.
What NvChad Is (and Is Not)
NvChad is a Neovim configuration framework built in Lua. It ships as a set of pre-configured plugins managed by lazy.nvim, with a consistent keybinding scheme and a custom UI layer. You get a working editor immediately after installation.
What NvChad is not:
- A plugin. You do not install it inside an existing Neovim config.
- A permanent black box. Everything is readable Lua; you can trace any behavior to source.
- A beginnerβs replacement for learning Vim motions. You still need to know how to move, select, and edit in Neovim. NvChad adds tooling on top, not instead of.
The relationship is: Neovim is the engine. NvChad is the car body.
Installation
NvChad requires Neovim 0.10 or later and a Nerd Font for icons. Install both before proceeding.
# on Arch / CachyOS
sudo pacman -S neovim
yay -S ttf-jetbrains-mono-nerd
# on Debian / Ubuntu
sudo apt install neovim
# install a nerd font manually from nerdfonts.com
# on macOS with Homebrew
brew install neovim
brew install --cask font-jetbrains-mono-nerd-font
Back up any existing Neovim config, then clone NvChad:
# backup existing config if any
mv ~/.config/nvim ~/.config/nvim.bak
mv ~/.local/share/nvim ~/.local/share/nvim.bak
# clone NvChad
git clone https://github.com/NvChad/starter ~/.config/nvim && nvim
On first launch, lazy.nvim installs all plugins. Wait for the installation to finish, then restart Neovim. You now have a working editor.
The NvChad UI
Before keymaps, understand the UI components you will interact with daily.
Tabufline β the top bar. It shows open buffers (files), not tabs in the traditional sense. Each open file is a buffer. You switch between them, not close and reopen files.
Statusline β the bottom bar. Shows current mode (NORMAL / INSERT / VISUAL), git branch, LSP diagnostics, file type, line/column position, and scroll percentage.
NvimTree β the file explorer on the left. Toggle it with <C-n>. It supports full file operations: create, rename, delete, copy, paste.
NvDash β the start screen shown when you open Neovim with no file argument. Navigate with arrow keys and Enter.
Cheatsheet β press <leader>ch at any time to open a floating window listing all NvChad keymaps organized by category.
Understanding <leader>
Nearly every NvChad keymap uses <leader> as its prefix. In NvChad, <leader> is set to Space. So when a keymap is written as <leader>ff, it means: press Space, then press f, then press f.
The <leader> key is a namespace. All custom keymaps live under it to avoid colliding with Vimβs native bindings. Once you internalize this, the entire keymap system becomes predictable.
Essential Keymaps by Category
File and Buffer Management
| Keymap | Action |
|---|---|
<C-n> | Toggle NvimTree file explorer |
<leader>e | Focus NvimTree |
<Tab> | Next buffer |
<S-Tab> | Previous buffer |
<leader>x | Close current buffer |
<leader>b | New buffer |
Buffers in Neovim are persistent. Closing a buffer with <leader>x does not close the window β it unloads the file. To close a split, use :q or <C-w>q.
Window Splits
| Keymap | Action |
|---|---|
<leader>h | Horizontal split |
<leader>v | Vertical split |
<C-h> | Move to left window |
<C-l> | Move to right window |
<C-j> | Move to lower window |
<C-k> | Move to upper window |
Window navigation uses <C-hjkl> β the same direction keys as Vim motions, but with Ctrl.
Telescope (Fuzzy Finder)
Telescope is the most used NvChad tool for navigation. It fuzzy-searches files, buffers, text, LSP symbols, and more.
| Keymap | Action |
|---|---|
<leader>ff | Find files |
<leader>fg | Live grep (search text in project) |
<leader>fb | Open buffers |
<leader>fh | Help tags |
<leader>fo | Old files (recent files) |
<leader>fz | Find in current buffer |
<leader>cm | Git commits |
<leader>gt | Git status |
<leader>pt | Colorscheme picker |
<leader>th | NvChad theme picker |
Inside any Telescope picker:
<C-j>/<C-k>β move up and down the listEnterβ open selected<C-v>β open in vertical split<C-x>β open in horizontal split<C-t>β open in new tab<Esc>β close picker
LSP Actions
LSP keymaps are active when an LSP server is attached to the current file. They provide IDE-level intelligence.
| Keymap | Action |
|---|---|
gd | Go to definition |
gD | Go to declaration |
gi | Go to implementation |
gr | Show references |
K | Hover documentation |
<leader>sh | Signature help |
<leader>ra | Rename symbol |
<leader>ca | Code actions |
<leader>d | Open float diagnostic |
[d | Previous diagnostic |
]d | Next diagnostic |
<leader>fm | Format file |
<leader>wa | Add workspace folder |
<leader>wr | Remove workspace folder |
gd and gr are the most used. Jump to definition to understand code, jump to references to find all usages.
Terminal
NvChad includes a toggle terminal powered by the nvterm plugin.
| Keymap | Action |
|---|---|
<A-h> | Toggle horizontal terminal |
<A-v> | Toggle vertical terminal |
<A-i> | Toggle floating terminal |
The floating terminal is the most useful for quick commands. Press <A-i>, run a command, press <A-i> again to hide it. The terminal session persists β it does not restart every time you toggle.
To exit terminal insert mode without closing it, press <C-x>.
Git Signs
gitsigns shows git changes in the sign column (the narrow column left of line numbers) and provides hunk navigation.
| Keymap | Action |
|---|---|
]c | Next hunk |
[c | Previous hunk |
<leader>rh | Reset hunk |
<leader>ph | Preview hunk |
<leader>gb | Git blame line |
<leader>td | Toggle deleted lines |
A βhunkβ is a contiguous block of changed lines. <leader>ph shows what was there before the change in a floating diff window.
Comment Toggle
| Keymap | Action |
|---|---|
<leader>/ | Toggle comment on current line |
<leader>/ (visual) | Toggle comment on selection |
Works with Treesitter context β so in an embedded language (TypeScript inside HTML, SQL inside Go strings) it uses the correct comment syntax.
Miscellaneous
| Keymap | Action |
|---|---|
<leader>ch | NvChad cheatsheet |
<Esc> | Clear search highlights |
<leader>n | Toggle line numbers |
<leader>rn | Toggle relative line numbers |
<leader>wK | Show all keymaps |
<leader>ma | Bookmarks (Telescope marks) |
NvimTree Keymaps
When focus is inside NvimTree, a different set of keymaps is active.
| Keymap | Action |
|---|---|
Enter or o | Open file or expand folder |
a | Create new file or folder (end name with / for folder) |
r | Rename |
d | Delete |
c | Copy |
x | Cut |
p | Paste |
y | Copy filename |
Y | Copy relative path |
gy | Copy absolute path |
<C-v> | Open in vertical split |
<C-x> | Open in horizontal split |
H | Toggle hidden files |
I | Toggle git ignored files |
R | Refresh tree |
q | Close NvimTree |
Creating a file: press a, type the filename including any subdirectory path. NvimTree creates missing directories automatically. To create a directory, end the name with /.
NvChad Commands
Beyond keymaps, several Vim commands are specific to NvChad or particularly useful.
:NvDash " open the dashboard
:NvCheatsheet " open the keymap cheatsheet (same as <leader>ch)
:Mason " open Mason package manager UI
:MasonInstallAll " install all LSP servers listed in your config
:MasonUpdate " update installed servers
:Lazy " open Lazy plugin manager UI
:Lazy sync " update all plugins
:Lazy clean " remove unused plugins
:TSUpdate " update Treesitter parsers
:TSInstall <lang>" install a Treesitter parser for a language
:LspInfo " show active LSP servers for current buffer
:LspLog " view LSP debug log
:checkhealth " diagnose Neovim and plugin health
Run :checkhealth whenever something behaves unexpectedly. It checks Neovim version, Python providers, Node.js, external binaries, and plugin status.
LSP Setup: Adding Language Servers
NvChad uses Mason to manage LSP servers, formatters, and linters. Open Mason with :Mason and browse the list. Press i to install a server.
For a more automated setup, declare the servers you want in your custom config. Create the file ~/.config/nvim/lua/custom/configs/lspconfig.lua:
-- ~/.config/nvim/lua/custom/configs/lspconfig.lua
local on_attach = require("plugins.configs.lspconfig").on_attach
local capabilities = require("plugins.configs.lspconfig").capabilities
local lspconfig = require("lspconfig")
-- servers that need no special configuration
local servers = { "html", "cssls", "ts_ls", "pyright", "bashls", "dockerls", "yamlls" }
for _, lsp in ipairs(servers) do
lspconfig[lsp].setup({
on_attach = on_attach,
capabilities = capabilities,
})
end
-- gopls needs specific settings for Go
lspconfig.gopls.setup({
on_attach = on_attach,
capabilities = capabilities,
settings = {
gopls = {
analyses = {
unusedparams = true,
shadow = true,
},
staticcheck = true,
gofumpt = true,
},
},
})
-- rust_analyzer
lspconfig.rust_analyzer.setup({
on_attach = on_attach,
capabilities = capabilities,
settings = {
["rust-analyzer"] = {
checkOnSave = { command = "clippy" },
},
},
})
Then install the matching binaries via Mason. For Go:
:MasonInstallAll
" or individually:
:MasonInstall gopls gofumpt goimports golangci-lint-langserver
After installing, reopen the file and run :LspInfo to confirm the server attached.
Customizing NvChad
NvChad separates its core from your personal config. Your custom files live in ~/.config/nvim/lua/custom/. When you update NvChad, your custom directory is never touched.
The entry point is ~/.config/nvim/lua/custom/chadrc.lua:
-- ~/.config/nvim/lua/custom/chadrc.lua
local M = {}
M.ui = {
theme = "catppuccin", -- set default theme
theme_toggle = { "catppuccin", "one_light" },
transparency = false,
statusline = {
theme = "default", -- "default" | "vscode" | "vscode_colored" | "minimal"
separator_style = "round", -- "default" | "round" | "block" | "arrow"
},
}
M.plugins = "custom.plugins" -- point to your plugins file
return M
Adding Plugins
Create ~/.config/nvim/lua/custom/plugins.lua:
-- ~/.config/nvim/lua/custom/plugins.lua
local plugins = {
-- override mason to install more servers
{
"williamboman/mason.nvim",
opts = {
ensure_installed = {
-- LSP servers
"gopls",
"ts_ls",
"pyright",
"rust-analyzer",
"lua-language-server",
-- formatters
"gofumpt",
"goimports",
"prettier",
"black",
-- linters
"golangci-lint",
"eslint_d",
},
},
},
-- override treesitter to install more parsers
{
"nvim-treesitter/nvim-treesitter",
opts = {
ensure_installed = {
"go", "gomod", "gosum", "gowork",
"typescript", "javascript", "tsx",
"python", "rust", "lua",
"sql", "yaml", "toml", "json",
"dockerfile", "hcl",
"markdown", "markdown_inline",
},
},
},
-- add a new plugin not in NvChad core
{
"folke/trouble.nvim",
cmd = "Trouble",
config = function()
require("trouble").setup()
end,
},
-- auto-pairing brackets and quotes
{
"windwp/nvim-autopairs",
event = "InsertEnter",
config = function()
require("nvim-autopairs").setup()
end,
},
-- surround text objects
{
"kylechui/nvim-surround",
event = "VeryLazy",
config = function()
require("nvim-surround").setup()
end,
},
}
return plugins
After saving, open Neovim and run :Lazy sync. Lazy installs new plugins and removes ones no longer in your list.
Adding Custom Keymaps
Create ~/.config/nvim/lua/custom/mappings.lua:
-- ~/.config/nvim/lua/custom/mappings.lua
local M = {}
M.general = {
n = {
-- save file
["<C-s>"] = { "<cmd>w<CR>", "Save file" },
-- quit
["<leader>q"] = { "<cmd>qa<CR>", "Quit all" },
-- trouble diagnostics
["<leader>tt"] = { "<cmd>Trouble diagnostics toggle<CR>", "Trouble diagnostics" },
-- format with LSP
["<leader>lf"] = {
function()
vim.lsp.buf.format({ async = true })
end,
"LSP format",
},
},
i = {
-- exit insert mode faster
["jk"] = { "<Esc>", "Escape insert mode" },
["kj"] = { "<Esc>", "Escape insert mode" },
},
}
return M
Reference this file in chadrc.lua:
M.mappings = require("custom.mappings")
Themes and Appearance
NvChad ships with 60+ themes. Switch interactively with <leader>th β a Telescope picker shows a live preview of each theme as you move through the list.
Themes persist across sessions. Your chosen theme is saved in ~/.local/share/nvim/nvchad_theme.
To set a default theme (so it loads immediately on startup without the picker), set it in chadrc.lua:
M.ui = {
theme = "gruvchad", -- any theme name from the picker
}
Popular NvChad themes:
catppuccinβ soft, pastel, easy on the eyes for long sessionsgruvchadβ warm brown palette, retro feelonedarkβ familiar VS Code-adjacent colorstokyonightβ cool blues and purplesnordβ desaturated arctic colors
Updating NvChad
NvChad has three independent update mechanisms: plugins, LSP servers, and Treesitter parsers. Update each separately.
" update all plugins (lazy.nvim)
:Lazy sync
" update Mason-managed servers and tools
:MasonUpdate
" update Treesitter parsers
:TSUpdate
After :Lazy sync, Lazy shows a summary of what was updated and whether anything failed. If a plugin update breaks something, you can pin it to a previous commit in your custom/plugins.lua:
{
"some/plugin",
commit = "abc1234", -- pin to specific commit
},
To update NvChadβs base config itself (the starter repo):
cd ~/.config/nvim
git pull origin main
Your lua/custom/ directory is git-ignored by the starter, so updates never touch your customizations.
Daily Workflow Patterns
Understanding the keymaps in isolation is less useful than seeing them in sequence during real work.
Opening a Project
nvim . # open NvimTree in current directory
<leader>ff # find a file to start in
gd (on a function call) # jump to definition
<Tab> / <S-Tab> # switch between open files
Searching and Navigating
<leader>fg # live grep β find a string anywhere in project
<C-j> / <C-k> # move through results
Enter # open the file at the match location
<leader>fb # switch to a specific open buffer
Working with LSP
K # read documentation for symbol under cursor
gd # jump to definition
gr # see all usages of the symbol
<leader>ca # apply a code action (auto-import, fix, refactor)
<leader>ra # rename symbol across all files
<leader>fm # format the file
[d / ]d # navigate between errors and warnings
Git Workflow
<leader>gt # Telescope git status β stage/unstage files
]c / [c # jump between changed hunks
<leader>ph # preview what changed in this hunk
<leader>gb # see who wrote the line under cursor (blame)
Running Code from the Editor
<A-i> # open floating terminal
go run ./cmd/api # run your project
<A-i> # hide terminal (session stays alive)
<A-i> # bring it back any time
Troubleshooting Common Issues
Icons appear as boxes or question marks. Your terminal is not using a Nerd Font. Set the font in your terminal emulator settings.
LSP not attaching. Run :LspInfo β if the server is not listed, run :Mason and install it. If it is listed but not attached, check :LspLog for errors.
Plugin not found after adding it. Run :Lazy sync after editing custom/plugins.lua.
Treesitter highlighting looks wrong. Run :TSUpdate and restart Neovim.
Slow startup. Run :Lazy profile to see which plugins take the most time to load. Add lazy = true or move to event = "VeryLazy" for non-critical plugins.
Telescope results are empty. Install ripgrep for grep results and fd for file results:
# Arch / CachyOS
sudo pacman -S ripgrep fd
# Debian / Ubuntu
sudo apt install ripgrep fd-find
# macOS
brew install ripgrep fd
The difference between a Neovim user and a Neovim power user is not the number of plugins β it is the depth of familiarity with the tools already there. NvChad gives you a complete set on day one. The investment is in learning it well: internalizing the keymaps until they require no thought, building the muscle memory for Telescope and LSP navigation, and understanding the customization layer well enough to extend without breaking.
A good editor does not make you faster by doing more for you. It makes you faster by disappearing β becoming invisible between the thought and the code.
Tags
Related Articles
Clean Architecture: Building Software that Endures
A comprehensive guide to Clean Architecture explained in human language: what each layer is, how they integrate, when to use them, and why it matters for your business.
Design Patterns: The Shared Vocabulary of Software
A comprehensive guide to design patterns explained in human language: what they are, when to use them, how to implement them, and why they matter for your team and your business.
Idiomatic Go: The mindset shift that transforms teams
A deep guide to what writing idiomatic Go means, why it is different, how to shift your thinking from object-oriented programming to interfaces, and why this makes your code better.