Why I Built nvim-starter — a Neovim Config Beginners Can Actually Understand — CoPilot Blog
    Neura MarketNeura Market/CoPilot
    ChatGPTChatGPTClaudeClaudeGeminiGeminiCursorCursorGrokGrokPerplexityPerplexityCoPilotCoPilot
    DeepSeekDeepSeekStable DiffusionStable DiffusionMidjourneyMidjourney
    View All Directories
    OverviewRulesPromptsMCPsAgentsBlogVideosGuidesCoursesCommunityPluginsTrendingGenerate
    CoPilotBlogWhy I Built nvim-starter — a Neovim Config Beginners Can Actually Understand
    Back to Blog
    Why I Built nvim-starter — a Neovim Config Beginners Can Actually Understand
    nvim

    Why I Built nvim-starter — a Neovim Config Beginners Can Actually Understand

    Marius van Zundert June 25, 2026
    0 views

    Kickstart.nvim gives you a working IDE. It also gives you lazy.nvim, nvim-cmp, telescope, nvim-treesitter, and a dozen concepts to learn before you've written a single line of config. I wanted something simpler.

    --- title: Why I Built nvim-starter — a Neovim Config Beginners Can Actually Understand published: true description: Kickstart.nvim gives you a working IDE. It also gives you lazy.nvim, nvim-cmp, telescope, nvim-treesitter, and a dozen concepts to learn before you've written a single line of config. I wanted something simpler. tags: nvim, lua, learning, developerlife cover_image: https://dev-to-uploads.s3.us-east-2.amazonaws.com/uploads/articles/ga6roijuxxjmce026ttg.png # Use a ratio of 100:42 for best results. # published_at: 2026-06-25 09:52 +0000 --- **Kickstart.nvim gives you a working IDE. It also gives you lazy.nvim, nvim-cmp, telescope, nvim-treesitter, and a dozen concepts to learn before you've written a single line of config. I wanted something simpler.** --- ## The problem with kickstart.nvim Let me be clear: kickstart.nvim is a good project. It's the standard recommendation for Neovim beginners, it's maintained by a core Neovim developer, and it ships a genuinely capable setup. I recommend it to people all the time. But every time I did, I'd watch them hit the same wall. They'd clone the repo, launch Neovim, see plugins install, and then freeze. Not because the config didn't work — because they couldn't *read* it. Here's what a beginner sees when they open kickstart.nvim's `init.lua`: First, a large `require('lazy').setup({...})` block with a DSL they've never seen before — `event`, `cmd`, `keys`, `dependencies`, `opts`, `config`. Before they've learned what `vim.opt` does, they're staring at lazy-loading triggers and event-driven plugin activation. Then nvim-cmp, which requires four separate source plugins (`cmp-nvim-lsp`, `cmp-buffer`, `cmp-path`, `cmp_luasnip`) and a configuration block that maps twenty keybindings, defines a formatting function, and wires up capabilities. Then telescope with its own setup and extension loading. Then nvim-treesitter with `ensure_installed`. Then mason-lspconfig with a manual `ensure_installed` list. None of this is wrong — it's just *a lot*. It's a production config dressed as a starter. The very things that make kickstart powerful (lazy-loading, modular plugin specs, extensible completion sources) are the things that make it illegible to someone who doesn't yet know what a plugin *is*. So I built nvim-starter. The goal: a configuration you can read top to bottom in ten minutes and walk away understanding. --- ## What nvim-starter does differently ### 1. No plugin manager This is the biggest decision I made, and the one that shapes everything else. Kickstart.nvim uses lazy.nvim. lazy.nvim is excellent software — Folke is a brilliant developer, and lazy.nvim rightfully became the standard. But it's an *abstraction layer* between you and your plugins. To understand the config, you first have to understand lazy.nvim's spec format: what `event = "VeryLazy"` means, how `cmd` triggers work, why some plugins use `dependencies` and others don't, what the `opts` shorthand expands to. For a beginner, this is backwards. They should be learning *Neovim's* concepts — buffers, windows, keymaps, options, LSP — not a plugin manager's DSL. nvim-starter uses `vim.pack.add()`, which shipped with Neovim 0.12. You give it a list of GitHub URLs: ```lua vim.pack.add({ { src = "https://github.com/folke/tokyonight.nvim", name = "tokyonight.nvim" }, { src = "https://github.com/folke/which-key.nvim", name = "which-key.nvim" }, { src = "https://github.com/folke/snacks.nvim", name = "snacks.nvim" }, -- ... }, { confirm = false }) ``` That's it. There is nothing to learn. Neovim clones these repos into its standard plugin directory, adds them to the runtimepath, and loads them the same way it's loaded plugins for decades. The "plugin manager" is the editor itself. When a beginner reads this block, they see exactly what's happening: here are the plugins, here are their URLs, they get installed automatically. No lazy-loading. No event triggers. No `after/` directories. Ten plugins load at startup, and with `vim.loader.enable()` (bytecode caching introduced in Neovim 0.12), startup time is imperceptible. For a starter config with ten plugins, the complexity of lazy-loading isn't worth the cognitive cost. ### 2. blink.cmp instead of nvim-cmp When kickstart.nvim was created, nvim-cmp was the only viable completion engine. It works, but it's a sprawling setup. You need: - `nvim-cmp` itself - `cmp-nvim-lsp` for LSP completions - `cmp-buffer` for buffer words - `cmp-path` for filesystem paths - `cmp_luasnip` for snippets - A capabilities bridge to wire it into the LSP client - A formatting function if you want pretty icons That's five plugins and a configuration block that typically runs 40–60 lines. blink.cmp — Saghen's Rust-based completion engine — bundles LSP, path, buffer, and snippet sources internally. The entire completion configuration in nvim-starter is 25 lines: ```lua require("blink.cmp").setup({ keymap = { preset = "none", ... }, sources = { default = { "lsp", "path", "snippets", "buffer" } }, snippets = { preset = "luasnip" }, }) ``` No separate source plugins. No capability bridging (one wildcard LSP config covers it). No formatting function. It's faster at runtime and dramatically simpler to read. blink.cmp is younger than nvim-cmp and has a smaller ecosystem, but for the four sources a starter config needs — LSP, path, snippets, buffer — it's the simpler tool. I'll take simpler over battle-tested for something meant to be read and understood before it's used. ### 3. snacks.nvim over telescope (and toggleterm, and neo-tree) telescope.nvim is a fantastic fuzzy finder. But it's *only* a fuzzy finder. If you also want a built-in terminal, you install toggleterm.nvim. A file explorer? neo-tree.nvim or nvim-tree.lua. Each of these has its own configuration syntax, its own keybindings, its own documentation to read. Folke's snacks.nvim bundles all three — picker, terminal, explorer — into one plugin with one setup call. In nvim-starter, the entire UI layer is 10 lines: ```lua require("snacks").setup({ explorer = { enabled = true }, terminal = { enabled = true }, picker = { matcher = { fuzzy = true, smartcase = true, filename_bonus = true } }, }) ``` One plugin to understand instead of three. One set of keybindings to learn. One repo to trust. For a beginner who hasn't yet internalized the difference between a picker, a terminal buffer, and a file tree, this collapsing of concepts is a genuine learning aid. ### 4. No nvim-treesitter — just what Neovim ships nvim-treesitter is another plugin that's excellent software and adds unnecessary complexity for beginners. It manages parser installations through `:TSInstall`, which means you're learning a plugin-specific command before you've learned `:help`. It has its own configuration syntax (`ensure_installed`, `highlight = { enable = true }`). It periodically prompts you about parser updates. Neovim 0.12 ships with built-in Treesitter support and includes parsers for C, Lua, Markdown, Vimscript, vimdoc, and Query. That covers the languages most new Neovim users encounter first: Lua for their config, Markdown for notes, and maybe C if they're systems-curious. For additional languages, you install parsers through your OS package manager: ```bash $ apt install tree-sitter-python $ apt install tree-sitter-rust ``` Or via the tree-sitter CLI: ```bash $ tree-sitter install python ``` No Neovim plugin involved. No `:TSInstall`. The FileType autocmd in nvim-starter silently skips languages without parsers using `pcall` — no errors, no prompts, no confusion. When a beginner eventually installs a parser, highlighting just works. This is a deliberate philosophical choice: parser management belongs to the OS, not to your editor's plugin system. ### 5. Zero per-server LSP configuration In most Neovim configs — including kickstart — every language server needs its own setup block: ```lua lspconfig.pyright.setup({ ... }) lspconfig.rust_analyzer.setup({ ... }) lspconfig.lua_ls.setup({ ... }) ``` Multiply this by however many languages you use, add capability merging and on_attach callbacks, and the LSP section alone can hit a hundred lines. nvim-starter takes a different approach. mason-lspconfig's `automatic_enable = true` means: if a server binary exists on disk (because the user installed it through Mason's UI), start it automatically. No per-server blocks. No boilerplate. Capabilities for blink.cmp are merged once, globally: ```lua vim.lsp.config("*", { capabilities = require("blink.cmp").get_lsp_capabilities(...), }) ``` One line. Every server, present and future, gets completion, signature help, and snippet capabilities. When I install `pyright` in Mason, it works. When I install `rust_analyzer`, it works. There is nothing to write, nothing to maintain, nothing to explain. For beginners, this transforms the LSP experience from "read the lspconfig docs for your language" to "open Mason, press `i` on the server you want, restart neovim." That's the level of friction I wanted. ### 6. Single-file, by design Kickstart.nvim starts as a single file but encourages modularization — its README suggests splitting into `lua/plugins/`, `lua/opts/`, `lua/keymaps/`. This is good practice for a growing config, but it's also the moment a beginner's understanding fragments. Suddenly the colorscheme is in one file, keymaps in another, and LSP config in a third, connected through `require()` calls that assume you understand Lua's module system. nvim-starter's CONTRIBUTING.md states it plainly: > **Stay single-file.** The whole point is a single `init.lua` with comments. The entire config is 363 lines, organized into 16 numbered sections. It starts with a comment block telling you the three most common tweaks (colorscheme, indent size, plugin list) and their line numbers. Section 0 enables the loader. Section 1 sets the leader key. Section 2 declares plugins. And so on, linearly, until section 16 enables Treesitter. You read it top to bottom. You understand it. Then you fork it, rename it, and build your own. nvim-starter isn't a framework you extend — it's a reference implementation you learn from and outgrow. --- ## Why I chose these specific plugins Every plugin in nvim-starter passed a simple test: *is this essential for a beginner, and is it the simplest implementation of what it does?* | Plugin | Why this one | |---|---| | **tokyonight.nvim** | Dark theme, well-maintained, widely used. Gruvbox is commented-out as an alternative on the very next line. | | **which-key.nvim** | Shows available keybindings when you pause on `<Space>`. Beginners don't memorize keymaps — they discover them. | | **snacks.nvim** | One plugin replaces three (fuzzy finder, terminal, explorer). Less to install, less to configure, less to read. | | **mason.nvim** + **mason-lspconfig.nvim** | GUI server installer + auto-wiring. Beginners shouldn't need to know where binaries live or how `cmd` tables work. | | **nvim-lspconfig** | The standard LSP configuration library. Still needed for server-specific defaults, even with `automatic_enable`. | | **blink.cmp** + **blink.lib** | Rust-based completion that bundles its sources. Faster and simpler than nvim-cmp's source-plugin ecosystem. | | **gitsigns.nvim** | Git gutter markers. Beginners use Git. Seeing what changed is immediately useful. | | **guess-indent.nvim** | Auto-detects indentation per file. Beginners open files from projects they didn't create — this saves them from mixing tabs and spaces. | | **LuaSnip** | Snippet expansion. Powers the snippet source in blink.cmp. The only plugin with a build hook (compiles its regex engine on install). | That's 10 plugins, 11 if you count blink.lib (a dependency of blink.cmp). No file tree, no statusline plugin, no debug adapter, no auto-formatter beyond LSP formatting. Each omission is documented in `docs/plugins.md` with recommendations if you want to add them later. --- ## What nvim-starter doesn't try to be **It's not your forever-config.** It's deliberately undersized. Once you're comfortable with Neovim, you'll want things it doesn't include — a statusline, a debug adapter, auto-formatting on save, session management. That's by design. nvim-starter gets you to the point where you *know* what you want to add, which is the real goal. **It's not modular.** There are no `lua/` subdirectories, no `require()` chains, no plugin specs split across files. This is a constraint, not an oversight. Modularity is the right call for a configuration you'll maintain for years — but it's the wrong call for a configuration meant to be read in one sitting. **It's not version-agnostic.** nvim-starter requires Neovim ≥ 0.12. This is a hard requirement and I'm comfortable with it. `vim.pack.add()` and native Treesitter are the right primitives for a beginner config, and they didn't exist before 0.12. Ubuntu 24.04 LTS ships Neovim 0.9.5, so you'll need a PPA, AppImage, or manual build. I think the trade-off — a simpler config that leverages editor-native features — is worth the install step. If Neovim 0.12 isn't available to you, use kickstart.nvim instead. --- ## What you get in five minutes Install it: ```bash curl -fsSL https://raw.githubusercontent.com/Mvzundert/nvim-starter/main/install.sh | bash ``` Open a file. Plugins clone for ~30 seconds. Then: | You get | Press | |---|---| | Keybinding cheat sheet | `<Space>` and wait | | Fuzzy file finder | `<Space>sf` | | Content search (grep) | `<Space>sg` | | LSP server installer (GUI) | `<Space>cm` | | Terminal toggle | `<Space>tt` | | File explorer | `<Space>e` | | Go-to-definition | `gd` (with LSP attached) | | Hover docs | `K` | | Rename symbol | `<Space>rn` | | Code actions | `<Space>ca` | | Auto-completion | Just type | | Format buffer | `<Space>f` | Install a language server by opening Mason (`<Space>cm`), pressing `2` for LSP servers, searching for your language, and pressing `i`. Reopen your file. Autocompletion, go-to-definition, and diagnostics all work. No config written. No docs read. Just a working IDE. --- ## The trade-offs I'm comfortable with Every design decision is a trade-off. Here are the ones I made and why I stand by them: **Neovim ≥ 0.12 only.** Yes, this excludes stable-distribution users. But `vim.pack.add()` eliminates the plugin manager abstraction entirely. That single simplification justifies the version requirement. Beginners installing Neovim fresh aren't tied to a distro package anyway — they're following a "how to install Neovim" tutorial that gives them the latest version. **No lazy-loading.** Ten plugins load at startup. On any machine built in the last decade, with `vim.loader.enable()` caching bytecode, this is under 50 milliseconds. The cognitive cost of explaining lazy-loading to a beginner vastly outweighs the performance gain. **blink.cmp instead of nvim-cmp.** blink.cmp is newer and has a smaller plugin ecosystem. But a beginner doesn't need custom completion sources — they need LSP completions, buffer words, and file paths. blink.cmp does all three out of the box with a 25-line config. If they eventually need a source blink.cmp doesn't support, they'll have learned enough to evaluate nvim-cmp themselves. **No `:LspInfo`.** Neovim 0.12 replaced `:LspInfo` with `:checkhealth vim.lsp`. This is documented in the README and in the inline comments, but I know it will trip up users following older tutorials. It's a Neovim upstream decision I can't control, and I think documenting it clearly is sufficient. **Built-in Treesitter requires extra steps for more languages.** If you work in Python, Rust, Go, TypeScript, Bash, and ten other languages, installing parsers through your package manager is an extra step per language. nvim-treesitter's `:TSInstall all` is genuinely more convenient for polyglots. But nvim-starter is for beginners — beginners typically work in one or two languages. Installing one or two tree-sitter packages isn't a meaningful burden, and avoiding nvim-treesitter keeps the plugin count down and the mental model simple. --- ## Why you might choose nvim-starter over kickstart.nvim Use nvim-starter if: - **You're new to Neovim and want to understand your config.** Kickstart works, but it's hard to read. nvim-starter is 363 lines of commented Lua that tells you exactly what every line does and why it's there. - **You don't want to learn a plugin manager before learning Neovim.** lazy.nvim is powerful, but it's an abstraction. nvim-starter uses `vim.pack.add()` — there is no plugin manager to learn because the editor *is* the plugin manager. - **You want to get productive in five minutes, not five hours.** Install, launch, install one LSP server, start coding. That's the workflow. There's no config to write. - **You learn by reading working code.** nvim-starter is a reference implementation. Read it top to bottom. Then delete it and write your own — you'll know enough. - **You prefer smaller dependency trees.** Fewer plugins, fewer repositories to trust, fewer version interactions to debug. Stick with kickstart.nvim if: - You need Neovim ≥ 0.9 compatibility (Ubuntu LTS, Debian stable, RHEL). - You want lazy-loading and fine-grained startup control. - You want nvim-cmp's mature plugin ecosystem. - You want `:TSInstall` convenience for dozens of languages. - You want a config you can grow modularly without rewriting from scratch. --- ## The bottom line I built nvim-starter because I believe the first Neovim configuration a beginner sees should be legible. They should be able to read it in one sitting, understand what every section does, and feel confident tweaking it. The plugins should auto-install without a plugin manager. The LSP should auto-wire without per-server configuration. The code should document itself. Kickstart.nvim is a launchpad. nvim-starter is a tutorial that happens to give you a working IDE. --- **Repository:** [github.com/Mvzundert/nvim-starter](https://github.com/Mvzundert/nvim-starter) **Requirements:** Neovim ≥ 0.12, Git, Nerd Font (optional) **License:** MIT

    Tags

    nvimlualearningdeveloperlife

    Comments

    More Blog

    View all
    Minimalist EKS: The Easy Waykubernetes

    Minimalist EKS: The Easy Way

    Amazon EKS manages the Kubernetes control plane, but you remain responsible for provisioning the...

    J
    Joaquin Menchaca
    Never forget to enter the Stern Grove lottery again!ai

    Never forget to enter the Stern Grove lottery again!

    Browser automation with Playwright, Python, GitHub Actions, and Entire to auto-enter San Francisco Stern Grove concert lotteries each week!

    L
    Lizzie Siegle
    A Free Screenshot Editor That Never Uploads Your Imagetypescript

    A Free Screenshot Editor That Never Uploads Your Image

    A free screenshot and image editor that runs entirely in your browser. Keeping every edit reversible and handling big phone photos, in plain TypeScript and Canvas2D.

    M
    Martin Stark
    I built a CLI to break my highlights out of Apple Booksshowdev

    I built a CLI to break my highlights out of Apple Books

    A macOS CLI + MCP server that exports Apple Books highlights to Markdown and gives AI assistants direct access to your reading notes.

    A
    Andrey Korchak
    A Developer's Guide to Agent Hooks in Antigravity CLIai

    A Developer's Guide to Agent Hooks in Antigravity CLI

    Motivation To be quite honest, "Hooks"—the shell commands we trigger at specific points...

    T
    Tanaike
    Tactical vs. Strategic Agentic AI Development — A Playbook for Developersagents

    Tactical vs. Strategic Agentic AI Development — A Playbook for Developers

    The Strategic Engineer: Why Writing Code Is No Longer Your Most Valuable Skill ...

    A
    Adewumi Saheed Adewale

    Stay up to date

    Get the latest CoPilot prompts, rules, and resources delivered to your inbox weekly.

    Neura Market LogoNeura Market

    Discover the best AI prompts, plugins, and resources for CoPilot and more.

    Content Types

    • Rules
    • Prompts
    • MCPs
    • Agents
    • Guides

    Platforms

    • ChatGPT Directory
    • Claude Directory
    • Gemini Directory
    • Cursor Directory
    • Grok Directory
    • Perplexity Directory
    • DeepSeek Directory
    • CoPilot Directory
    • Stable Diffusion Directory
    • Midjourney Directory
    • All Directories

    Resources

    • Blog
    • Documentation
    • Help Center
    • Marketplace

    Legal

    • Privacy Policy
    • Terms of Service

    © 2026 Neura Market. All rights reserved.

    |

    Not affiliated with any AI platform vendors.