Debugging Go in Nvim doesn’t have to be daunting

edgar rubioedgar rubio
3 min read

You might have peeked at Nvim and thought, “Programming feels cool again!” But if you're coming from a popular IDE like IntelliJ or VSCode, debugging might seem like a daunting task.

Background

Two years ago, I was curious enough to give Nvim a serious try — with the goal of switching completely. Coming from IntelliJ (Java) and VSCode (JS/TS), one of the biggest barriers I encountered was debugging.

To be honest, I mostly got by using console.log() or printf statements.

Thankfully, LazyVim helps reduce the friction significantly, especially for those of us used to full-featured IDEs. In this tutorial, I’ll walk you through how to set up Go debugging using LazyVim.

Requirements

  • LazyVim
    A pre-configured Nvim setup that includes sensible defaults, useful plugins, and powerful UI enhancements. It simplifies the Nvim learning curve for developers coming from IDEs.

  • Delve (dlv)
    The standard debugger for Go. It enables stepping through code, inspecting variables, and managing breakpoints — all essential for debugging.

  • nvim-dap
    A Debug Adapter Protocol (DAP) client for Nvim. It provides the core functionality needed to run, control, and interact with debuggers inside Nvim.

  • nvim-dap-go
    A Go-specific extension for nvim-dap that simplifies Delve integration and provides Go-friendly defaults.

  • dap.core and dap.lua (from LazyVim Extras)
    Plugin presets provided by LazyVim to enable nvim-dap support with minimal configuration. They include setup helpers and sensible defaults.

Installation

1. Install Delve

go install github.com/go-delve/delve/cmd/dlv@latest

2. Enable DAP Extras in LazyVim

Open the LazyVim plugin manager (via <leader>l), scroll to Extras, and enable the following:

  • dap.core

  • dap.lua

Enable dap.core and dap.lua in LazyVim extras

3. Add nvim-dap-go to Your Plugin Config, create or update lua/plugins/dap.lua

return {
  "mfussenegger/nvim-dap",
  dependencies = {
    "leoluz/nvim-dap-go",
  },
  config = function()
    require("dap-go").setup()
  end,
}

4. Sync Plugins

After saving your config, restart Nvim and run:

:Lazy sync

Getting Started with Debugging

Once everything is set up, you're ready to debug Go code inside Nvim. Feel free to use this simple http server.

package main

import (
    "fmt"
    "net/http"
)

func helloHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "Hello, World!")
}

func main() {
    http.HandleFunc("/", helloHandler)

    fmt.Println("Server is running on http://localhost:8080")
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        fmt.Println("Error starting server:", err)
    }
}

Basic Keybindings:

  • Set a breakpoint: <leader>db, for example inside the helloHandler function.

  • Start debugging: <leader>dc this will launch the DAP UI by default.

  • In a separate terminal, make a request to trigger the breakpoint:

curl http://localhost:8080
  • Now that the process is stopped at the breakpoint, explore available debugging commands: <leader>d
    (e.g., dc, dO, di, etc.)

DAP UI running inside Neovim

What’s Next?

Now that you’ve got debugging working for standard Go apps in Nvim, you might be wondering:

“But what about CLI apps that use TTY input/output?”

In Part 2, I’ll walk through how to debug Go applications that run in the terminal, accept input, and interact with TTY — where Delve needs a bit of extra help.

0
Subscribe to my newsletter

Read articles from edgar rubio directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

edgar rubio
edgar rubio