← Writing

Writing my Neovim config from scratch

2026-05-02

ToolsEngineeringNeovim

A two-part Medium series on building a Neovim setup from a blank init.lua — bootstrap, options, keymaps, lazy.nvim, then the plugin layer that makes it a real editor.

In 2024 I rebuilt my editor from scratch. No distros, no preset, no Cursor — just init.lua, lazy.nvim, and a folder of plugin files I actually understand.

The full config lives at ~/.config/nvim under a lua/arkash/ namespace — core/ (options + keymaps), lazy.lua (bootstrap), and plugins/ (one Lua file per plugin so I can rip any of them out without surprises).

The two-part write-up

I wrote it up as I went, on Medium:

  • Part 1 — Writing my Neovim config from scratch. Why I did it, the bootstrap, options that actually matter (relativenumber, signcolumn, clipboard:append("unnamedplus"), splits right/below), and a leader-centric keymap layout. → medium.com/@arkjain/writing-my-neovim-config-from-scratch

  • Part 2 — Adding Plugins to my Config: No Punches Pulled Back Now. Telescope, nvim-tree, lualine, bufferline, treesitter, gitsigns, which-key, todo-comments, conform, nvim-lint, mason + lspconfig + cmp/luasnip, aerial, alpha — the whole plugin layer, one file at a time. → medium.com/@arkjain/adding-plugins-to-my-config

What's worth stealing

A few opinionated bits that survived two years of daily use:

  • One file per plugin under plugins/. lazy.nvim auto-imports them via { import = "arkash.plugins" }. Adding a plugin is a single new file; removing one is rm. No giant table to merge into.
  • <leader> = <space> and stay disciplined about what gets a leader binding. Window and tab management are leader-prefixed (<leader>sv, <leader>to); search/clear highlights is <leader>nh. Everything else stays out of the way.
  • auto-session + sane defaults beat any project-management plugin I tried — open Neovim in the directory and your buffers/splits are restored.
  • mason for binary management, mason-tool-installer to declare the toolchain in code. No more "did I npm i -g typescript-language-server on this machine?".
  • conform.nvim for formatting, nvim-lint for linting. Both are built around the idea that you already have prettierd / ruff / eslint_d on disk — they don't try to be a package manager too.

2026 update — what got added

Since the Medium series, six plugins made it into the core lineup:

  • harpoon (ThePrimeagen/harpoon, branch harpoon2) — pinned-file fast-switch; <leader>ha to add, <leader>hh for the menu, <leader>h1..<leader>h4 to jump.
  • flash.nvim (folke/flash.nvim) — label-based motion that replaced easymotion / sneak; s to jump, S for treesitter labels.
  • trouble.nvim (folke/trouble.nvim) — diagnostics / quickfix / loclist in one panel; <leader>xx toggles.
  • oil.nvim (stevearc/oil.nvim) — edit a directory as a buffer; <leader>o opens it. Kept nvim-tree as the primary tree, oil for surgical filesystem edits.
  • nvim-surround (kylechui/nvim-surround)ys{motion}{char} add, ds{char} delete, cs{old}{new} change.
  • undotree (mbbill/undotree)<leader>u to visualize the undo branches.

The philosophy remains: one file per plugin, leader-prefixed bindings, no distro. The config stays human-scale and transparent.

The repo is at github.com/ArkashJ/NeoDotfiles. The README in that repo has the full keymap table.