How to set up Vim for Go Development

One of the major reasons I love programming in Go is that I can do it in any IDE or editor I want, including my favourite Vim editor.

Unlike Java, for example, which is highly coupled to IntelliJ or Eclipse, Go is much more lightweight and the tools you use with it can be integrated with any editor.

In this guide, I will help you setup your Vim as a fully-fledged Go IDE, including the plugins you need to install but also setting up the important options & mappings which you'll use daily.


You'll need to have Go installed & your Go environment setup, namely your $GOPATH and related subdirectories - /bin /pkg /src.

You'll also need to use nvim instead of vim or have your vim updated to version 8+.

The Main Vim plugin for Go

One of the only plugins you need for Go is called vim-go. It aggregates all the tools you need to get started with Go development.

To install it via pathogen:

git clone ~/.vim/bundle

Other installation options.

After you've installed it, you can customise it using these options which are highly opinionated, but work best for me:

" disable all linters as that is taken care of by coc.nvim
let g:go_diagnostics_enabled = 0
let g:go_metalinter_enabled = []

" don't jump to errors after metalinter is invoked
let g:go_jump_to_error = 0

" run go imports on file save
let g:go_fmt_command = "goimports"

" automatically highlight variable your cursor is on
let g:go_auto_sameids = 0

For syntax highlighting, use these options:

let g:go_highlight_types = 1
let g:go_highlight_fields = 1
let g:go_highlight_functions = 1
let g:go_highlight_function_calls = 1
let g:go_highlight_operators = 1
let g:go_highlight_extra_types = 1
let g:go_highlight_build_constraints = 1
let g:go_highlight_generate_tags = 1

Finally, install all the required go tools by opening vim and running:


coc.nvim - Autocompletion & linting

In the past, I've relied on YouCompleteMe for auto-completion or vim-go's native integration with vim for auto-completion & ALE for linting/static code analysis.

Nowadays, I prefer using coc.nvim and its plugins to do all that as I've found it to be more reliable than all of those tools.

For installation instructions, follow the Quick Start guide.

After you've installed it, run this command to install the necessary coc extension for Go:

vim -c 'CocInstall -sync coc-go coc-html coc-css coc-json|q'

The html/css/json extensions are optional but who doesn't deal with those nowadays. You'd probably need them at some point.

Afterwards, open vim & type :CocConfig to open coc's configuration file. These are my opinionated settings, stripped from the non-go related settings:

  "suggest.noselect": false,
  "diagnostic.errorSign": "✘",
  "diagnostic.warningSign": "!",
  "diagnostic.infoSign": "?",
  "diagnostic.checkCurrentLine": true,
  "coc.preferences.formatOnSaveFiletypes": [
  "coc.preferences.hoverTarget": "float",
  "languageserver": {
    "golang": {
      "command": "gopls",
      "rootPatterns": ["go.mod"],
      "filetypes": ["go"]
  "go.goplsOptions": {
    "staticcheck": true

For all auxiliary coc settings, add these settings to your .vimrc.

Mappings For The Most Useful Commands

Having great tools is not enough. You need to know how to use them. Hence, it is best to customize some of the mappings which vim-go and coc provide you so that you're more effective when dealing with Go code.

Here are the mappings I use most often and the way I've configured them:

Manage unit tests in the current file

I've mapped running all the tests in the current file to <leader>-t which translates to \ + t on my Mac & Linux.

autocmd BufEnter *.go nmap <leader>t  <Plug>(go-test)

I've also mapped \ + tt to run the current test function only, instead of running all of them:

autocmd BufEnter *.go nmap <leader>tt <Plug>(go-test-func)

Finally, I use \ + c to toggle the coverage profile for the current file I'm in:

autocmd BufEnter *.go nmap <leader>c  <Plug>(go-coverage-toggle)

Inspect a Go Codebase

Show the function signature for a given routine with \ + i:

autocmd BufEnter *.go nmap <leader>i  <Plug>(go-info)

Show the interfaces a type implements with \ + ii:

autocmd BufEnter *.go nmap <leader>ii  <Plug>(go-implements)

Describe the definition of a given type with \ + ci:

autocmd BufEnter *.go nmap <leader>ci  <Plug>(go-describe)

See the callers of a given function with \ + cc:

autocmd BufEnter *.go nmap <leader>cc  <Plug>(go-callers)

Find all references of a given type/function in the codebase with \ + cr:

nmap <leader>cr <Plug>(coc-references)

Go to definition/Go back with Ctrl+d and Ctrl+a:

nmap <C-a> <C-o>
nmap <C-d> <Plug>(coc-definition)

Refactor Go Code

Not many options here, but there's renaming the symbol your cursor is on with \ + r:

nmap <leader>r <Plug>(coc-rename)

Occasional Maintenance of Tooling

To update all Go tools, run this from vim:


And updating all coc plugins:


To upgrade vim-go or coc.nvim, delete the folders from ~/.vim/bundle and git clone the repos again.

Setup The Cool gruvbox Theme (Optional)

Install gruvbox using pathogen:

git clone ~/.vim/bundle

Enable it in your .vimrc with some opinionated extra options:

colorscheme gruvbox
autocmd ColorScheme * highlight CocErrorFloat guifg=#ffffff
autocmd ColorScheme * highlight CocInfoFloat guifg=#ffffff
autocmd ColorScheme * highlight CocWarningFloat guifg=#ffffff
autocmd ColorScheme * highlight SignColumn guibg=#adadad

Want to see how it looks?

Setup tmux For Terminal Multiplexing (Optional)

If you want to manage multiple terminal tabs in the same window, use tmux (See my how to guide):

This is one of the most useful tools I have setup because it allows me to do my code editing in vim and manage all sorts of other terminal-related tasks in separate tabs all inside the same window.


And that's everything I use for my daily Go programming.

This setup has worked extremely well for me and have in mind that I'm also dealing with Uber's huge Go Monorepo, where I've been able to integrate my vim environment seamlessly (with some extra settings which you probably won't need.

If you want to see my entire vim development environment, check out all my dotfiles and default-setups repos, which include my full setup, including external programs, the terminal, vim, tmux, colorschemes, etc.

Happy Gophing!

Check out some of my other Go series:
Integrating your Go Service with ELK
gRPC With Go Crash Course

gRPC With Go Crash Course

gRPC With Go Crash Course

In this crash course, we'll cover everything you need to know about gRPC and integrating it with your Go applications.

Each of the sub-articles below are written in a way that they are independent from one another, so if you're interested in only going through a specific part of the course, feel free to do so.

The only article which is mandatory is the Introduction, which covers what kind of application you'll be building as well as what kind of software you need to install/configure to avoid any technical issues throughout the course.

If you encounter any issues or bugs in the article/code, feel free to open an issue in the Github repo for this course.

If you enjoy the course & want to support me I'd be more than grateful if you ⭐ the repo, share the series, say thanks on Twitter or sponsor my work 🙏

Continue Reading

gRPC with Go Crash Course – Bidirectional Streams

gRPC with Go - Bidirectional Streams

This article is part of the series gRPC With Go Crash Course

In this part of the course, you will implement the most challenging RPC routine type which gRPC has to offer - bidirectional streams.

These routines are used to achieve bidirectional client-server communication - meaning that communication can flow both ways. A way to achieve this using traditional HTTP technologies is via web sockets. With gRPC, you have support for such communication natively.

Continue Reading

gRPC With Go Crash Course – Unidirectional Streams

gRPC with Go - Unidirectional Streams

This article is part of the series gRPC With Go Crash Course

In this part of the course, you will implement slightly more challenging RPC routines which involve utilising the gRPC streaming capabilities.

These are essentially a way to achieve client-side or server-side pagination. However, in contrast to normal HTTP APIs, in gRPC these streaming utilities are first-class citizens rather than a useful add-on (e.g. via web sockets).

There is also support for bidirectional streams, which we will explore in the follow-up exercise. In this one, we’ll focus on unidirectional (client-side/server-side) streaming RPCs.

Continue Reading

gRPC With Go Crash Course – Service Schemas

gRPC with Go - Service Schemas

This article is part of the series gRPC With Go Crash Course

In this article, you will create a gRPC/Protobuf schema for a small micro service system for an online casino. 

The scope of the article is to: 

  • Create the service schemas
  • Correctly generate the protobuf Go sources
  • Implement the gRPC servers/clients for the appropriate microservices
  • Integrate the microservices with each other
Continue Reading

gRPC With Go Crash Course – Introduction

gRPC with Go - Introduction

This article is part of the series gRPC With Go Crash Course

In the following set of articles, you'll learn how gRPC works by building several simple web applications and hook them together using gRPC.

The articles won't go into details of what gRPC is and what's its purpose. There's a lot of existing material on the subject already. Instead, they focus on helping you get some real practice using gRPC, integrating it into your own applications & understanding the core mechanisms it provides.

First, we'll cover what we're about to build & the environment setup you'll need for the rest of the articles.

Additionally, have in mind that all the parts of the course are written in a way that they are independent from each other. So if you're not interested in the whole course and want to jump straight to Bidirectional Streams (for example), feel free to do so.

Continue Reading

Thread-Safety in Go – an Overlooked Concern

Thread-Safety in Go - An overlooked concern
Gopher on image was designed by Renee French. (

When you first start tinkering with concurrency in any language, what's the most sought after goal is extracting the maximum output from the hardware you have available.

That's why we use it and study it in the first place - to achieve optimal parallelism & get some significant speed-up for our apps out of the box.

However, a not so glamorous part of studying the subject is understanding how to write thread-safe code. The techniques and principles which will enable you to keep your application well-behaved, even after scaling it to dozens of threads.

Even though this is an important thing to consider while writing concurrent code, it is often overlooked in most learning resources about concurrency. This problem is even more relevant in the Go community due to two common misunderstandings I will cover in the article.

Continue Reading

Speaking at Golab Conf this year!

This year, I'm going to be presenting at Golab Conf about Advanced Dependency Management in Go using Fx. I'm also hosting a workshop on integrating your Go service \w the ELK stack.

In the talk, we'll cover what the Fx framework is and how it can help you reduce some of the component wiring boilerplate as well as help you structure your applications into reusable modules, which is especially great in a microservice environment!

As for the workshop, it's a VERY hands-on 3-hour workshop in which you'll learn how to use the Elastic stack to greatly enhance your services' observability. If you have no idea what all that means, then this workshop is definitely for you. It will give you the knowledge to evaluate if these tools are right for you and the skills to fully integrate this into your systems & start using it right away.

If any of that sounds interesting to you, then book your seat!

Otherwise, check out the full agenda here as there are also other pretty cool talks & some quite interesting workshops!

The conference is hosted online throughout 19th October to 25th October from the comfort of your own seat at home.

The "Advanced Dependency Management in Go using Fx" talk is held on 16th October, 17:30 PM GMT +2.

The "Integrating your Go service with the ELK stack" workshop is held on 21st October, 12:30 PM GMT+2.

I'll see you there!


The videos from the talk + workshop are out. Check them out:

Advanced Dependency Management in Go using Fx

Workshop - Integrating your Go service with the ELK stack

Site Footer