Check Go module dependencies and update them from a go.mod buffer in Neovim.
Dependency status appears as virtual text, and a floating picker lets you choose
which outdated modules to update.
- Neovim 0.12 or newer
- Go 1.27.3 or newer, available as
goin Neovim'sPATH - A Nerd Font for the default icons, or your own text icons
Support and CI track the latest stable Go release; legacy Go toolchains are not maintained. CI runs the offline standalone specs with the latest stable Go on Ubuntu with Neovim v0.12.0, and on Ubuntu and macOS with stable Neovim.
With lazy.nvim:
{
"syz51/go-mod.nvim",
version = "*", -- latest stable tagged release
ft = "gomod",
opts = {},
}With another plugin manager, install syz51/go-mod.nvim on your runtime path. The plugin initializes automatically on the first
go.mod file. Explicit setup is optional; use it to customize defaults:
require("go-mod").setup({
check_interval = 30, -- minutes
})A file already open when setup runs is also eligible for automatic checking.
Create ~/.config/nvim/lua/plugins/go-mod.lua:
return {
{
"syz51/go-mod.nvim",
version = "*",
ft = "gomod",
opts = {
check_interval = 60,
},
},
}Restart Neovim and run :Lazy install go-mod.nvim. Open a go.mod file to
load the plugin and start checking dependencies, then run :checkhealth go-mod.
The plugin remains unloaded for unrelated filetypes. opts is passed to
require("go-mod").setup() automatically; no custom config function or
separate setup call is needed. No LazyVim Go extra or Plenary dependency is
required.
version = "*" selects tagged stable releases, overriding LazyVim's default
of following the repository branch. Use :Lazy update go-mod.nvim to get a
newer release. For an exact pin, replace version with tag = "v0.1.2".
- Open a
go.modfile. Withauto_check = true, the plugin checks its required module paths for available versions. - Run
:GoModCheckto check manually. After editing, save the file, then run:GoModCheckbefore updating. - Run
:GoModUpdateto open the picker, or:GoModUpdate example.com/moduleto update one outdated module. Command completion lists outdated module paths. - Review the resulting
go.modandgo.sumchanges and run your project's tests.
| Command | Action |
|---|---|
:GoModCheck |
Check the current go.mod buffer |
:GoModToggle |
Toggle dependency virtual text |
:GoModUpdate [module] |
Pick updates, or update the named outdated module |
:GoModLog |
Open the configured log file |
:GoModSetup |
Initialize with defaults; optional when using automatic loading |
:checkhealth go-mod |
Check prerequisites and configuration |
In the picker, move with normal Neovim motions and use:
| Key | Action |
|---|---|
Space, Enter on a module row |
Toggle that module |
a |
Toggle all selections |
u |
Update selected modules |
U |
Update all listed modules |
Tab, Shift-Tab |
Move between footer actions; press Enter to activate |
Esc, q, c |
Close the picker |
No global key mappings are installed. For example, add a buffer-local mapping
from your own FileType autocmd:
vim.api.nvim_create_autocmd("FileType", {
pattern = "gomod",
callback = function(args)
vim.keymap.set("n", "<leader>mc", "<cmd>GoModCheck<CR>", {
buffer = args.buf,
silent = true,
})
end,
})Checks and updates run in the directory of the original go.mod, even if you
change buffers or Neovim's working directory. Updates reject unsaved buffers or
files changed since the check, including changes on disk. Selected versions are
passed together to one go get command so Go resolves their constraints as a
group. Conflicting selections fail; results are refreshed afterward.
Avoid concurrent external edits while Go is running. Edits made in the buffer
during an update are preserved and require a reload and a fresh check.
With a positive check_interval, loaded go.mod buffers receive periodic
refreshes even without leaving and re-entering the buffer.
All options are optional. Defaults:
require("go-mod").setup({
icons = {
outdated = " ",
up_to_date = " ",
unpublished = " ",
error = " ",
},
virtual_text = {
prefix = "●",
spacing = 4,
},
highlights = {
outdated = "DiagnosticWarn",
up_to_date = "DiagnosticHint",
unpublished = "DiagnosticInfo",
error = "DiagnosticError",
},
auto_check = true,
notify_on_load = true, -- notify once when a loaded buffer first starts fetching
check_interval = 60, -- minutes; 0 disables timer and re-entry refreshes
log_level = "info", -- trace, debug, info, warn, error
log_file = vim.fn.stdpath("cache") .. "/go-mod.log", -- "" disables file logging
max_concurrent_jobs = 4, -- concurrent version lookups
timeout = 30000, -- milliseconds per Go process
})virtual_text.prefix is displayed before each status and spacing controls its
separation from the source line. Set auto_check = false and
check_interval = 0 for manual checking only.
An interval of 0 keeps the initial automatic check but disables periodic and
re-entry refreshes. unpublished means the current version compares newer than
the returned latest version; it does not establish that a version was never
published.
notify_on_load shows an INFO notification titled go-mod.nvim when each loaded
buffer starts its first dependency version lookup. It applies to automatic and
manual checks, independently of log_level. Saves and later checks do not repeat
it; unloading and reloading the buffer resets it. Empty files, files with only
invalid versions, and checks cancelled before a lookup starts do not notify.
Set it to false to disable it.
- Version checks query the original required module path upstream. They do not check a local replacement's contents or treat its version as the upstream version. Private or offline lookups can fail.
- Go handles updates and respects applicable
replacedirectives. The plugin does not rewrite replacements or migrate imports and module paths across major-version boundaries such asexample.com/libtoexample.com/lib/v2. go getcan change transitive dependencies andgo.sum, and, depending on your Go version and project, Go or toolchain directives. Review its changes.- Go uses the process and project environment, including
GOPROXY,GOPRIVATE, credentials, workspace settings, and applicable Go configuration. The plugin does not configure private registry access for you. - Updates reject an effective
GOFLAGS=-modfile=...setting, including one saved withgo env -w, because it redirects writes away from the opengo.mod. Remove that setting before updating with this plugin.
See the Go modules reference for Go's resolution and versioning rules.
Run :checkhealth go-mod and confirm :echo executable('go') returns 1.
Use :set filetype? to check that the buffer is gomod. Save changes, then run
:GoModCheck. For lookup failures, run go list -m -json module/path@latest
in the directory containing that go.mod, using the same environment as
Neovim. Check :GoModLog for details; logging must have a nonempty log_file.
Use log_level = "debug" temporarily when investigating, and remove private
paths, module names, and credentials before sharing logs.
See :help go-mod for commands and Lua APIs. Development and local checks are
covered in CONTRIBUTING.md.
Tagged versions are available on the releases page.
To pin a release with lazy.nvim, add tag = "v0.1.2" to the installation spec.
For supported security versions and private vulnerability reports, see SECURITY.md.
MIT, copyright (c) 2025 Roy Sun.