C.W.K.
Stream
Lesson 04 of 04 · published

kickstart.nvim and Performance Tips

~13 min · neovim, kickstart, performance, lazy-loading

Level 0Trapped
0 XP0/35 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete

kickstart.nvim — the official starter

nvim-lua/kickstart.nvim is a single, well-commented init.lua (around 800 lines, every section explained) that sets up LSP, completion, treesitter, telescope, gitsigns, mini.nvim, and a sensible keymap. Maintained by Neovim core contributors and updated for Neovim 0.11+. It's not a framework — it's a starting config you read and modify, not import as a black box.

When to use kickstart

  • Brand new to Neovim and want a working setup in 5 minutes.
  • Setting up a new machine and don't want to re-derive your config from scratch.
  • Teaching someone Neovim and want them on a known-good base.

Read every line as you adopt it. Every chunk has comments telling you what it does and why. Treat it as a learning config, not a dependency.

Performance — the budget you have

Modern Neovim with lazy.nvim should start in under 100ms. Measure first, optimize second:

  • :Lazy profile — total startup time and per-plugin breakdown.
  • nvim --startuptime /tmp/startup.log — full startup trace at the millisecond level.

Lazy-loading patterns that actually save time

Good lazy-loading defers heavy plugins until they're needed. Bad lazy-loading creates bugs because dependencies aren't loaded before you use them. The safe pattern is to lazy-load on a specific trigger that matches the plugin's usage:

  • event = "BufReadPost" — load when a file opens. Use for editing-time plugins (gitsigns, treesitter, comment plugins).
  • event = "InsertEnter" — load on first Insert mode. Use for completion (nvim-cmp, autopairs).
  • event = "VeryLazy" — load after the UI is ready. Use for plugins that don't need to be present immediately (which-key, lualine, nvim-surround).
  • cmd = "FugitiveStatus" — load on a specific command. Use for occasional-use heavy plugins (fugitive, Mason).
  • ft = { "python", "lua" } — load only for specific filetypes. Use for language-specific plugins.
  • keys = { ... } — load on a key first being pressed.

Custom Lua you'll write within a year

The Neovim API is rich enough that most personal automations are 5–15 lines of Lua. Three patterns you'll keep reaching for:

  • vim.api.nvim_create_autocmd — react to events (file opened, file saved, cursor held).
  • vim.api.nvim_create_user_command — define your own :Command.
  • vim.keymap.set + a custom function — bind anything you can write in Lua to a key.

Neovim's roadmap (peek ahead)

  • Neovim 0.12 (in flight) — built-in plugin manager via vim.pack, multi-cursor support, improved progress messages, vim.snippet as a first-class snippet system.
  • Neovim 0.13+ — structured concurrency (vim.async), multibuffer editing, more native features that today require plugins.

Don't chase the latest unstable. Stay on the latest stable (0.11.x as of 2026); upgrade when 0.12.0 lands and the plugin ecosystem catches up.

The endgame: a config you've outgrown nothing in. After a year or two, your init.lua reflects every real preference you have. Plugins were added because you felt their absence; mappings exist because you typed the long form twice. That's the editor that fits your hand. Vim+tmux earns its lifetime ROI in that config.

Code

Try kickstart.nvim — single command·bash
# Back up your existing config first!
mv ~/.config/nvim ~/.config/nvim.bak 2>/dev/null
mv ~/.local/share/nvim ~/.local/share/nvim.bak 2>/dev/null

# Clone kickstart.nvim as your config
git clone https://github.com/nvim-lua/kickstart.nvim ~/.config/nvim

# Open Neovim — it will install everything automatically on first run
nvim
Profile your startup·vim
:Lazy profile          " interactive — pick the slowest plugin

" Or, from the shell:
$ nvim --startuptime /tmp/startup.log +q
$ tail -50 /tmp/startup.log    " the rightmost number is each step's cost
Custom Lua — three patterns you'll write yourself·lua
-- Highlight yanked text briefly
vim.api.nvim_create_autocmd("TextYankPost", {
  callback = function()
    vim.highlight.on_yank({ higroup = "IncSearch", timeout = 200 })
  end,
})

-- Custom :Format command
vim.api.nvim_create_user_command("Format", function()
  vim.lsp.buf.format({ async = true })
end, { desc = "Format buffer with LSP" })

-- Toggle diagnostics on a key
vim.keymap.set("n", "<leader>td", function()
  local enabled = vim.diagnostic.is_enabled()
  vim.diagnostic.enable(not enabled)
  vim.notify("Diagnostics " .. (enabled and "off" or "on"))
end, { desc = "Toggle diagnostics" })
Lazy-loading reference card·lua
-- BufReadPost: when an existing file is opened
{ "plugin", event = { "BufReadPost", "BufNewFile" } }

-- InsertEnter: first time you go into Insert mode
{ "plugin", event = "InsertEnter" }

-- VeryLazy: after UI is fully drawn (set by lazy.nvim)
{ "plugin", event = "VeryLazy" }

-- Specific command
{ "plugin", cmd = "DoTheThing" }

-- Specific filetype
{ "plugin", ft = { "python", "lua" } }

-- First key press
{ "plugin", keys = { { "<leader>x", "<cmd>X<CR>" } } }

External links

Exercise

Run :Lazy profile on your current config — note the total startup time and the slowest three plugins. Pick the slowest plugin you'd be OK lazy-loading and add an event, cmd, or keys trigger to its spec. Re-profile. The point isn't to win the fastest-startup game; it's to feel how lazy-loading triggers actually work. Bonus: skim kickstart.nvim's init.lua top to bottom — it's a tour of how every layer in this quest fits together.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.