Neovim | Complete IDE Tutorial

A quick and painless guide on installing and configuring Neovim, and how to use it as your full daily driver IDE, btw.

Neovim | Complete IDE Tutorial

How to Install and Configure Neovim (2025 Guide)

A clean and painless guide to turning Neovim into a modern IDE.

Neovim is a Vim-based text editor built for extensibility and usability. In this tutorial, you’ll learn how to set it up with plugins, keybinds, and full LSP support. This guide assumes you’re using a Unix-like system and are comfortable with basic terminal commands.


1. Install Neovim and dependencies

Use your system’s package manager to install Neovim, along with a few tools that will be required later (like npm and ripgrep).

# Gentoo example
sudo emerge app-editors/neovim
sudo emerge net-libs/nodejs
sudo emerge sys-apps/ripgrep

# Arch example
sudo pacman -S neovim nodejs npm ripgrep

2. Set up your Neovim config directory

We’ll create the config folder and add our main config file, init.lua.

mkdir -p ~/.config/nvim
cd ~/.config/nvim
nvim .

Inside Neovim, press % to create a new file named init.lua. Then add a test print:

print("I use Neovim by the way")

Save and quit with :wq, then reopen Neovim. You should see the printed message.


3. Create a Lua module for options

Neovim’s Lua-based config allows us to split logic. Let’s make an options.lua file to set basic editor preferences.

mkdir -p ~/.config/nvim/lua/config
nvim lua/config/options.lua

Add some basic options:

vim.opt.number = true
vim.opt.relativenumber = true
vim.opt.cursorline = true
vim.opt.shiftwidth = 4

Now, require it in init.lua:

require("config.options")

4. Add keybindings

We’ll set our leader key and create a shortcut to open netrw quickly.

nvim lua/config/keybinds.lua
vim.g.mapleader = " "
vim.keymap.set("n", "<leader>cd", vim.cmd.Ex)

And include it in your init.lua:

require("config.keybinds")

5. Install Lazy.nvim (plugin manager)

Lazy is a modern plugin manager. Clone it into your runtime path:

-- lua/config/lazy.lua
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)

require("lazy").setup({})

Include Lazy in init.lua:

require("config.lazy")

6. Add a theme plugin

Add a plugin for theming and set it up with Lazy.

-- lua/plugins/colors.lua
return {
  "folke/tokyonight.nvim",
  config = function()
    vim.cmd.colorscheme("tokyonight")
  end,
}

7. Add Telescope for fuzzy finding

Telescope allows you to search files, text, and buffers.

-- lua/plugins/telescope.lua
return {
  "nvim-telescope/telescope.nvim",
  dependencies = { "nvim-lua/plenary.nvim" },
  config = function()
    local builtin = require("telescope.builtin")
    vim.keymap.set("n", "<leader>ff", builtin.find_files)
    vim.keymap.set("n", "<leader>fg", builtin.live_grep)
    vim.keymap.set("n", "<leader>fb", builtin.buffers)
    vim.keymap.set("n", "<leader>fh", builtin.help_tags)
  end,
}

8. Add Treesitter for syntax highlighting

Treesitter provides fast and accurate syntax parsing.

-- lua/plugins/treesitter.lua
return {
  "nvim-treesitter/nvim-treesitter",
  build = ":TSUpdate",
  config = function()
    require("nvim-treesitter.configs").setup({
      highlight = { enable = true },
      indent = { enable = true },
      ensure_installed = { "lua" },
      auto_install = false,
    })
  end,
}

9. Add Harpoon for file bookmarking

Harpoon lets you quickly switch between frequently edited files.

-- lua/plugins/harpoon.lua
return {
  "ThePrimeagen/harpoon",
  config = function()
    local harpoon = require("harpoon")
    vim.keymap.set("n", "<leader>a", function() harpoon:list():add() end)
    vim.keymap.set("n", "<C-e>", function() harpoon.ui:toggle_quick_menu(harpoon:list()) end)
  end,
}

10. Add LSP, autocompletion, and snippets

For full IDE features, you’ll need LSP config, autocompletion, and snippets.

-- lua/plugins/lsp.lua
return {
  "neovim/nvim-lspconfig",
  dependencies = {
    "williamboman/mason.nvim",
    "hrsh7th/nvim-cmp",
    "L3MON4D3/LuaSnip",
  },
  config = function()
    require("mason").setup()
    require("mason-lspconfig").setup({ ensure_installed = { "lua_ls" } })

    local lspconfig = require("lspconfig")
    lspconfig.lua_ls.setup({})

    local cmp = require("cmp")
    cmp.setup({
      snippet = {
        expand = function(args)
          require("luasnip").lsp_expand(args.body)
        end,
      },
      mapping = cmp.mapping.preset.insert({
        ["<Tab>"] = cmp.mapping.select_next_item(),
        ["<S-Tab>"] = cmp.mapping.select_prev_item(),
      }),
      sources = { { name = "nvim_lsp" }, { name = "luasnip" } },
    })
  end,
}

11. One-liner utility plugins

Throw small config-free utilities into one file to avoid bloat.

-- lua/plugins/oneliners.lua
return {
  { "tpope/vim-fugitive" },
  { "ojroques/nvim-osc52" },
  { "norcalli/nvim-colorizer.lua", config = function()
      require("colorizer").setup()
    end,
  },
}

Final init.lua Example

require("config.options")
require("config.keybinds")
require("config.lazy")

Lazy will automatically load any plugin files inside lua/plugins.


You’re now ready to use Neovim as a modern, fast, and extensible code editor. Questions? Drop them in the comments.

Related Posts

Arch Linux Install Guide (UEFI, 2025 Edition)

Arch Linux Install Guide (UEFI, 2025 Edition)

  • July 22, 2025
  • Tony, btw

A quick and painless guide on installing Arch, btw.

Gentoo Linux Install Guide (2026 Edition)

Gentoo Linux Install Guide (2026 Edition)

  • July 22, 2025
  • Tony, btw

A quick and painless guide on installing Gentoo, btw.