Skip to content
Dev Tools Beginner Tutorial

Turn Neovim into a Full IDE with LSP, Treesitter, and Telescope

One init.lua takes bare Neovim 0.12 to autocomplete, fuzzy finding, and syntax-aware navigation.

Lenn Voss
Lenn Voss
Cloud & Infrastructure Writer · Aug 17, 2026 · 4 min read
Turn Neovim into a Full IDE with LSP, Treesitter, and Telescope

What you'll build

Starting from a bare Neovim install and one init.lua, you'll end up with a language-aware editor: syntax-aware highlighting via Treesitter, fuzzy file/text search via Telescope, and a working language server with go-to-definition, rename, and autocomplete — no distribution, no copied kitchen-sink config.

Prerequisites

Verified against Neovim 0.12.4 (stable), lazy.nvim (stable branch), nvim-treesitter main, telescope.nvim latest release, and mason.nvim 2.3.1.

  • Neovim ≥ 0.12 — the nvim-treesitter rewrite requires it. macOS: brew install neovim. Linux: distro packages lag badly; grab the tarball or AppImage from Neovim's releases page.
  • git and a C compiler (clang or gcc — on macOS, xcode-select --install) for cloning plugins and compiling parsers.
  • ripgrep (brew install ripgrep / apt install ripgrep) — Telescope's live_grep won't work without it.
  • tree-sitter CLI ≥ 0.26.1brew install tree-sitter, cargo install tree-sitter-cli, or a release binary. The nvim-treesitter README explicitly says not to install it via npm.

Back up any existing config first: mv ~/.config/nvim ~/.config/nvim.bak.

1. Bootstrap the plugin manager

Create ~/.config/nvim/init.lua. Everything in this tutorial goes in this one file, top to bottom. Start with lazy.nvim, which installs itself on first launch:

vim.g.mapleader = " "
vim.g.maplocalleader = "\\"

local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not (vim.uv or vim.loop).fs_stat(lazypath) then
  vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable",
    "https://github.com/folke/lazy.nvim.git", lazypath })
end
vim.opt.rtp:prepend(lazypath)

require("lazy").setup({
  spec = {
    { "nvim-treesitter/nvim-treesitter", branch = "main", lazy = false, build = ":TSUpdate" },
    { "nvim-telescope/telescope.nvim", version = "*",
      dependencies = { "nvim-lua/plenary.nvim" } },
    { "mason-org/mason.nvim", opts = {} },
    { "neovim/nvim-lspconfig" },
  },
})

Leader must be set before lazy.setup so plugin keymaps bind correctly.

2. Syntax-aware highlighting with Treesitter

nvim-treesitter's main branch is a full rewrite: no more configs.setup{}. You install parsers, then start highlighting per filetype. Append:

require("nvim-treesitter").install({ "lua", "python", "javascript" })
vim.api.nvim_create_autocmd("FileType", {
  pattern = { "lua", "python", "javascript" },
  callback = function() vim.treesitter.start() end,
})

Swap in the languages you actually use; parsers compile in the background on first launch.

3. Fuzzy finding with Telescope

telescope.nvim is already in the spec above — it just needs keymaps. Append:

local builtin = require("telescope.builtin")
vim.keymap.set("n", "<leader>ff", builtin.find_files, { desc = "Find files" })
vim.keymap.set("n", "<leader>fg", builtin.live_grep, { desc = "Live grep" })
vim.keymap.set("n", "<leader>fb", builtin.buffers, { desc = "Buffers" })
vim.keymap.set("n", "<leader>fh", builtin.help_tags, { desc = "Help tags" })

4. Wire up a language server

Since 0.11, LSP config is native: nvim-lspconfig now just ships ready-made configs that you activate with vim.lsp.enable(), and mason.nvim installs the server binaries and puts them on Neovim's PATH. Append:

vim.lsp.enable("lua_ls")

We're using the Lua server because your config is Lua — instant dogfooding. Now launch nvim, let lazy.nvim finish cloning, then install the server and restart:

:MasonInstall lua-language-server
:qa

Neovim 0.11+ ships LSP keymaps by default: grn rename, grr references, gra code action, gri implementation, gO document symbols, K hover, Ctrl-] definition.

5. Turn on autocomplete

No completion plugin needed — the built-in LSP completion autotriggers as you type. Append:

vim.api.nvim_create_autocmd("LspAttach", {
  callback = function(ev)
    local client = assert(vim.lsp.get_client_by_id(ev.data.client_id))
    if client:supports_method("textDocument/completion") then
      vim.lsp.completion.enable(true, client.id, ev.buf, { autotrigger = true })
    end
  end,
})

Accept a completion with Ctrl-y.

Verify it works

Open your own config: nvim ~/.config/nvim/init.lua, then run :checkhealth vim.lsp. You should see lua_ls listed under active clients:

- Active Clients: ~
  - lua_ls (id: 1)

Then confirm each piece: :checkhealth nvim-treesitter shows the installed parsers with no errors, keywords in your config are colored by Treesitter, K on vim.keymap pops up docs, typing vim.fn. in insert mode opens a completion menu, and <Space>ff opens the Telescope file picker.

Troubleshooting

  • module 'nvim-treesitter.configs' not found — you pasted a pre-rewrite snippet from an older tutorial. The main branch has no configs module; use the install() + vim.treesitter.start() pattern from step 2.

  • lua-language-server is not executable on opening a Lua file — the server isn't installed yet or Mason hasn't loaded. Run :MasonInstall lua-language-server, then restart Neovim.

  • Undefined global 'vim' diagnostics all over init.lua — lua_ls doesn't know it's inside Neovim. Add above vim.lsp.enable("lua_ls"):

    vim.lsp.config("lua_ls", {
      settings = { Lua = { diagnostics = { globals = { "vim" } } } },
    })
    
  • live_grep shows nothing — ripgrep is missing. :checkhealth telescope will flag rg: not found; install it and restart.

Next steps

Add servers for your real languages the same way: :MasonInstall pyright, then vim.lsp.enable("pyright") — nvim-lspconfig's README lists every config name. From there: telescope-fzf-native for faster sorting, nvim-treesitter-textobjects for syntax-aware motions, format-on-save via the LspAttach example in :help lsp-attach, and Neovim 0.12's experimental built-in vim.pack if you'd rather drop the plugin manager entirely.

Sources & further reading

  1. Neovim LSP documentation — neovim.io
  2. lazy.nvim Installation — lazy.folke.io
  3. nvim-treesitter (main branch) README — github.com
  4. telescope.nvim README — github.com
  5. mason.nvim README — github.com
  6. nvim-lspconfig README — github.com
Lenn Voss
Written by
Lenn Voss · Cloud & Infrastructure Writer

Lenn writes about cloud platforms, Kubernetes internals, and the infrastructure decisions that quietly make or break engineering organizations. Based in Berlin's vibrant tech scene, they have a talent for turning dense platform-engineering topics into prose that people actually finish reading.

Discussion 0

Join the discussion

Sign in or create an account to comment and vote.

No comments yet

Be the first to weigh in.

Related Reading