Skip to content
whoami

Set up Neovim with LazyVim

Turn Neovim into a full editor with LazyVim, with support for Go, TypeScript, Terraform, Docker, Helm and YAML, a transparent Tokyo Night theme, and Claude Code one key away.

Platform
macOS on Apple silicon
Time
About 20 minutes
Steps
11

Neovim is a fast, keyboard-driven text editor that runs in your terminal. LazyVim is a ready-made Neovim setup that adds a file explorer, fuzzy search, code completion, language servers and Git tools, and stays easy to change. This guide installs both and turns on support for Go, TypeScript, Terraform, Docker, Helm, JSON and YAML. It then adds a few personal touches: a transparent Tokyo Night theme, jj to leave insert mode, a Kubernetes-friendly YAML formatter, and Claude Code in a split. Run every command in Ghostty.

Verified with Neovim 0.12.5 · LazyVim 16.0.1 · macOS 27.0

steps

  1. Step 1: Install Neovim and its helpersNeovim itself, plus the search, Git and parser tools LazyVim uses.

    Install Neovim and the command line tools LazyVim relies on:

    Terminal
    brew install neovim ripgrep fd fzf lazygit tree-sitter-cli

    What each one does:

    • neovim is the editor. You start it with nvim.
    • ripgrep and fd power the search across file contents and file names.
    • fzf is a fuzzy finder that LazyVim's health check looks for.
    • lazygit is a full Git screen you can open inside Neovim.
    • tree-sitter-cli builds the parsers behind accurate syntax highlighting, using the C compiler that came with Homebrew.

    Check the version:

    Terminal
    nvim --version | head -1
    Expected output (yours may be newer)
    NVIM v0.12.5

    LazyVim needs Neovim 0.11.2 or newer.

  2. Step 2: Install the language toolsGo, Node.js, yamlfmt and OpenTofu, which the language support calls behind the scenes.

    LazyVim installs language servers for you, but it builds some of them with Go or Node.js, and two formatters in this setup run their own programs. Install all four:

    Terminal
    brew install go node yamlfmt opentofu
    • go lets LazyVim install gopls, the Go language server, along with the Go formatters and debugger.
    • node lets it install the TypeScript, JSON, YAML and Docker language servers.
    • yamlfmt formats YAML the way Kubernetes manifests are usually written.
    • opentofu provides tofu fmt and tofu validate for your Terraform files.

    If you already have Node.js from another installer, such as nvm or fnm, leave node out of the command.

  3. Step 3: Install the LazyVim starterBack up any Neovim setup you already have, then copy LazyVim's starter config into place.

    Neovim keeps its settings in ~/.config/nvim, and its plugins, history and cache in three more folders. This moves any of them that already exist aside, with the date in the name, so nothing is lost:

    Terminal
    stamp=$(date +%Y%m%d-%H%M%S)
    for d in ~/.config/nvim ~/.local/share/nvim ~/.local/state/nvim ~/.cache/nvim; do
      [ -e "$d" ] && mv "$d" "$d.bak-$stamp"
    done

    Now copy the starter config, then delete its Git history so the config is yours to change and track:

    Terminal
    git clone https://github.com/LazyVim/starter ~/.config/nvim
    rm -rf ~/.config/nvim/.git

    Do not start Neovim yet. The next steps finish the config first, so the first start installs everything in one go.

  4. Step 4: Turn on the language extrasGo, TypeScript, Terraform, Docker, Helm, JSON and YAML support, plus a debugger, Harpoon, mini.files and mini.surround.

    LazyVim keeps optional features, called extras, switched off until you ask for them. You can pick them one at a time with the :LazyExtras command, which saves your choices to lazyvim.json. Writing that file yourself turns them all on at once:

    Terminal
    [ -f ~/.config/nvim/lazyvim.json ] && cp ~/.config/nvim/lazyvim.json ~/.config/nvim/lazyvim.json.bak-$(date +%Y%m%d-%H%M%S)
    cat > ~/.config/nvim/lazyvim.json <<'EOF'
    {
      "extras": [
        "lazyvim.plugins.extras.coding.mini-surround",
        "lazyvim.plugins.extras.dap.core",
        "lazyvim.plugins.extras.editor.harpoon2",
        "lazyvim.plugins.extras.editor.mini-files",
        "lazyvim.plugins.extras.lang.docker",
        "lazyvim.plugins.extras.lang.go",
        "lazyvim.plugins.extras.lang.helm",
        "lazyvim.plugins.extras.lang.json",
        "lazyvim.plugins.extras.lang.terraform",
        "lazyvim.plugins.extras.lang.typescript",
        "lazyvim.plugins.extras.lang.yaml"
      ],
      "install_version": 8,
      "version": 8
    }
    EOF

    What you get:

    • coding.mini-surround: keys to add, change and delete quotes and brackets around text.
    • dap.core: a debugger with breakpoints and step-through.
    • editor.harpoon2: pin a handful of files and jump between them with one key.
    • editor.mini-files: a file browser you edit like a normal text buffer.
    • lang.docker: Dockerfile and Compose language servers, plus the hadolint linter.
    • lang.go: gopls, gofumpt, goimports and the Delve debugger.
    • lang.helm: Helm chart templates.
    • lang.json: JSON with schema checks.
    • lang.terraform: the Terraform language server and the tflint linter.
    • lang.typescript: the TypeScript and JavaScript language server.
    • lang.yaml: YAML with schema checks, including Kubernetes manifests.

    The two version numbers tell LazyVim this is a fresh install, so it uses its current defaults for file search and the file explorer.

  5. Step 5: Set your options and keysWrap long lines, fold only when you ask, hide the tab line, and type jj or jk to leave insert mode.

    LazyVim loads your own options from lua/config/options.lua. Add three to the end of it:

    Terminal
    grep -q 'showtabline = 0' ~/.config/nvim/lua/config/options.lua || cat >> ~/.config/nvim/lua/config/options.lua <<'EOF'
    
    vim.opt.wrap = true -- wrap long lines instead of scrolling sideways
    vim.opt.foldmethod = "manual" -- fold only when you ask, with zf
    vim.opt.showtabline = 0 -- never show the tab line at the top
    EOF

    In files it understands, LazyVim switches folding to follow the structure of the code, which would override the manual setting. This file stops that, so folds appear only where you make them:

    Terminal
    [ -f ~/.config/nvim/lua/plugins/folds.lua ] && cp ~/.config/nvim/lua/plugins/folds.lua ~/.config/nvim/lua/plugins/folds.lua.bak-$(date +%Y%m%d-%H%M%S)
    cat > ~/.config/nvim/lua/plugins/folds.lua <<'EOF'
    -- Keep foldmethod = "manual" in every file
    return {
      { "nvim-treesitter/nvim-treesitter", opts = { folds = { enable = false } } },
      { "neovim/nvim-lspconfig", opts = { folds = { enabled = false } } },
    }
    EOF

    Next, make jj and jk leave insert mode, so you can keep your hands on the home row instead of reaching for Esc:

    Terminal
    grep -q '"jj"' ~/.config/nvim/lua/config/keymaps.lua || cat >> ~/.config/nvim/lua/config/keymaps.lua <<'EOF'
    
    -- Leave insert mode by typing jj or jk
    vim.keymap.set("i", "jj", "<Esc>", { desc = "Leave insert mode" })
    vim.keymap.set("i", "jk", "<Esc>", { desc = "Leave insert mode" })
    EOF

    The grep -q checks skip each append if it is already there, so running them twice is safe.

  6. Step 6: Make Tokyo Night transparent and drop the buffer tabsTokyo Night with a see-through background, so your Ghostty colors show through, and no row of open files along the top.

    LazyVim already uses the Tokyo Night theme. This makes its background, side panels and pop-ups transparent, so the editor sits on your Ghostty background. It also turns off bufferline, the row of open files along the top:

    Terminal
    [ -f ~/.config/nvim/lua/plugins/colorscheme.lua ] && cp ~/.config/nvim/lua/plugins/colorscheme.lua ~/.config/nvim/lua/plugins/colorscheme.lua.bak-$(date +%Y%m%d-%H%M%S)
    cat > ~/.config/nvim/lua/plugins/colorscheme.lua <<'EOF'
    return {
      {
        "LazyVim/LazyVim",
        opts = {
          colorscheme = "tokyonight",
        },
      },
      {
        "folke/tokyonight.nvim",
        opts = {
          transparent = true,
          styles = {
            sidebars = "transparent",
            floats = "transparent",
          },
        },
      },
    }
    EOF
    [ -f ~/.config/nvim/lua/plugins/bufferline.lua ] && cp ~/.config/nvim/lua/plugins/bufferline.lua ~/.config/nvim/lua/plugins/bufferline.lua.bak-$(date +%Y%m%d-%H%M%S)
    cat > ~/.config/nvim/lua/plugins/bufferline.lua <<'EOF'
    return {
      { "akinsho/bufferline.nvim", enabled = false },
    }
    EOF

    Without the tabs you still switch between open files with Shift+H and Shift+L, or pick one from a list with Space then ,.

  7. Step 7: Shorten the surround keysAdd and delete quotes and brackets around text with sa and sd.

    The mini.surround extra adds, deletes and replaces pairs such as quotes and brackets. All its keys start with gs by default. This shortens the two you will use most to sa and sd:

    Terminal
    [ -f ~/.config/nvim/lua/plugins/surround.lua ] && cp ~/.config/nvim/lua/plugins/surround.lua ~/.config/nvim/lua/plugins/surround.lua.bak-$(date +%Y%m%d-%H%M%S)
    cat > ~/.config/nvim/lua/plugins/surround.lua <<'EOF'
    return {
      "nvim-mini/mini.surround",
      opts = {
        mappings = {
          add = "sa",
          delete = "sd",
          find = "gsf",
          find_left = "gsF",
          highlight = "gsh",
          replace = "gsr",
          update_n_lines = "gsn",
        },
      },
    }
    EOF

    A few examples, with the cursor on a word:

    Keys What it does
    saiw" Wrap the word in double quotes
    sd" Delete the double quotes around the cursor
    gsr"' Change double quotes to single quotes
    saiw) Wrap the word in parentheses

    Pressing s on its own still starts LazyVim's Flash jump after a short pause.

  8. Step 8: Format YAML for Kubernetes and Terraform with OpenTofuyamlfmt for YAML that matches Kubernetes manifests, and tofu fmt and tofu validate for Terraform files.

    LazyVim formats a file every time you save it. The YAML extra's default formatter indents list items under their parent key, which Kubernetes manifests usually do not. This switches YAML to yamlfmt with lists kept flush with their key:

    Terminal
    [ -f ~/.config/nvim/lua/plugins/conform.lua ] && cp ~/.config/nvim/lua/plugins/conform.lua ~/.config/nvim/lua/plugins/conform.lua.bak-$(date +%Y%m%d-%H%M%S)
    cat > ~/.config/nvim/lua/plugins/conform.lua <<'EOF'
    return {
      "stevearc/conform.nvim",
      opts = {
        formatters_by_ft = {
          yaml = { "yamlfmt" }, -- Kubernetes-friendly YAML
        },
        formatters = {
          yamlfmt = {
            -- lists flush with their key, as kubectl writes them
            prepend_args = { "-formatter", "indentless_arrays=true" },
          },
        },
      },
    }
    EOF

    The Terraform extra formats and checks files with the terraform program. This points both at OpenTofu instead:

    Terminal
    [ -f ~/.config/nvim/lua/plugins/opentofu.lua ] && cp ~/.config/nvim/lua/plugins/opentofu.lua ~/.config/nvim/lua/plugins/opentofu.lua.bak-$(date +%Y%m%d-%H%M%S)
    cat > ~/.config/nvim/lua/plugins/opentofu.lua <<'EOF'
    return {
      {
        "stevearc/conform.nvim",
        opts = {
          formatters_by_ft = {
            terraform = { "tofu_fmt" },
            tf = { "tofu_fmt" },
            ["terraform-vars"] = { "tofu_fmt" },
          },
        },
      },
      {
        "mfussenegger/nvim-lint",
        opts = {
          linters_by_ft = {
            terraform = { "tofu" },
            tf = { "tofu" },
          },
        },
      },
    }
    EOF

    Go needs nothing extra: the Go extra already turns on gofumpt formatting, automatic imports and staticcheck in gopls. To format without saving, press Space then c then f.

  9. Step 9: Start Neovim for the first timeLazyVim installs every plugin, language server and parser on its own, then a health check confirms it all works.

    Start Neovim:

    Terminal
    nvim

    The first start takes a minute or two. A window lists each plugin as it installs. When it finishes, press q to close it. Mason, LazyVim's installer for language servers and formatters, keeps working in the background and reports each tool in the corner as it lands.

    Once the messages stop, quit with :qa and start nvim again, so everything loads cleanly. Then check that LazyVim has what it needs:

    Text
    :checkhealth lazyvim

    Every line should start with OK. To see the language tools Mason installed, open its window with :Mason, and press q to close it.

  10. Step 10: Open Claude Code inside NeovimoptionalTurn on LazyVim's Claude Code extra to run Claude in a split that sees your open files and selections.

    This step needs Claude Code, from the Claude Code guide. LazyVim has an extra for it, built on the claudecode.nvim plugin. Turn it on from inside Neovim:

    1. Type :LazyExtras and press Enter.
    2. Type /claudecode and press Enter to jump to ai.claudecode.
    3. Press x to turn it on, then q to close the window.
    4. Quit with :qa and start nvim again.

    Every Claude key starts with Space then a:

    Keys What it does
    Space a c Open or close Claude in a split
    Space a f Move the cursor into Claude's split
    Space a b Add the current file to the conversation
    Space a s Send the selected lines, in visual mode
    Space a r Pick an earlier conversation to resume
    Space a a Accept the change Claude proposes
    Space a d Reject the change Claude proposes

    When Claude wants to edit a file, Neovim shows the change as a side-by-side diff, and nothing is saved until you accept it.

  11. Step 11: Neovim cheat sheetThe keys you will use every day in this setup.

    LazyVim's leader key is Space. Press it and wait, and a menu shows every key that can follow.

    Keys What it does
    jj or jk Leave insert mode
    Space Space Find a file by name
    Space / Search the text of every file
    Space e Open or close the file explorer
    Space f m Browse the current folder with mini.files
    Space , Switch between open files
    Shift+H / Shift+L Previous or next open file
    Space H Pin the current file to Harpoon
    Space h Show your pinned files
    Space 1 to 9 Jump to pinned file 1 to 9
    g d Go to where a name is defined
    K Show the documentation for the name under the cursor
    Space c a Show fixes and code actions
    Space c f Format the file
    Space g g Open lazygit
    Space d b Set a breakpoint
    Space d c Start or continue debugging
    Space s k Search every key binding
    Space q q Quit Neovim

    To change anything later, edit the files in ~/.config/nvim/lua/, then restart Neovim.

sources