Antes do Go Modules, gerenciar dependências em Go era confuso — GOPATH, dep, glide, govendor… Cada um tinha sua ferramenta. Com o Go Modules (introduzido no Go 1.11 e estabilizado no 1.13), finalmente temos uma solução oficial e integrada à linguagem.

O que é Go Modules?

Go Modules é o sistema oficial de gerenciamento de dependências do Go. Ele controla:

  • Quais dependências seu projeto usa
  • Quais versões de cada dependência
  • Integridade das dependências (hashes)

O arquivo go.mod é o coração do sistema — equivalente ao requirements.txt do Python ou package.json do Node.

Inicializando um módulo

mkdir meu-projeto && cd meu-projeto
go mod init github.com/Pardim93/meu-projeto

Isso cria o go.mod:

module github.com/Pardim93/meu-projeto

go 1.21

Adicionando dependências

Quando você importa um package e roda go build, o Go automaticamente adiciona a dependência:

package main

import (
    "fmt"
    "github.com/gorilla/mux"
)

func main() {
    r := mux.NewRouter()
    fmt.Println("Router criado!")
}
go build
# O Go baixa gorilla/mux automaticamente

O go.mod é atualizado:

module github.com/Pardim93/meu-projeto

go 1.21

require github.com/gorilla/mux v1.8.0

E o go.sum é criado com hashes de integridade.

Comandos essenciais

# Adicionar uma dependência específica
go get github.com/gorilla/mux@v1.8.0

# Atualizar para última versão
go get -u github.com/gorilla/mux

# Atualizar todas as dependências
go get -u ./...

# Remover dependências não usadas
go mod tidy

# Verificar integridade
go mod verify

# Baixar dependências para cache local
go mod download

# Listar dependências
go list -m all

# Ver o porquê de uma dependência existir
go mod why github.com/gorilla/mux

Versionamento semântico

Go Modules usa semver (Semantic Versioning):

v1.2.3
│ │ │
│ │ └── Patch: correções de bugs
│ └──── Minor: novas features (backward compatible)
└────── Major: breaking changes

No go.mod:

require (
    github.com/lib/pq v1.10.4          // versão exata
    github.com/redis/go-redis/v9 v9.0.2 // v9 é um módulo diferente
)

Major versions

Se um package muda a API (breaking change), ele muda o caminho do módulo:

// v0 e v1: mesmo caminho
github.com/foo/bar

// v2+: caminho diferente
github.com/foo/bar/v2

No seu código:

import "github.com/foo/bar/v2"

Replace directives

Útil para desenvolvimento local ou forks:

// go.mod
module github.com/meu/projeto

require github.com/dependencia/v2 v2.1.0

// Apontar para versão local durante desenvolvimento
replace github.com/dependencia/v2 => ../dependencia

// Apontar para um fork
replace github.com/dependencia/v2 => github.com/meu-fork/dependencia/v2 v2.1.1

Vendor mode

Para ambientes onde não é possível baixar dependências (CI restrito, air-gapped environments):

# Copia todas as dependências para ./vendor
go mod vendor

# Build usando vendor
go build -mod=vendor

# Atualizar vendor após mudanças no go.mod
go mod vendor

O diretório vendor/ deve ser commitado nesses casos.

go.sum: o que é?

O go.sum contém hashes criptográficos de cada versão de dependência:

github.com/gorilla/mux v1.8.0 h1:...
github.com/gorilla/mux v1.8.0/go.mod h1:...

Ele garante que ninguém adulterou o código após você ter baixado. Sempre commit o go.sum.

Dicas práticas

1. Sempre rode go mod tidy antes de commit:

go mod tidy
git add go.mod go.sum
git commit -m "Update dependencies"

2. Use go mod graph para visualizar dependências:

go mod graph | head -20

3. Use go mod edit para edições programáticas:

# Adicionar um replace
go mod edit -replace github.com/old/pkg=github.com/new/pkg@v1.0.0

# Setar a versão Go
go mod edit -go=1.21

4. Cache global:

O Go mantém um cache global em ~/go/pkg/mod. Múltiplos projetos compartilham o mesmo cache, economizando espaço e tempo.

Comparação com outras linguagens

Feature Go Modules pip (Python) npm (Node)
Arquivo de config go.mod requirements.txt package.json
Lock file go.sum requirements.txt (pinado) package-lock.json
Gerenciado pelo build Sim Não Não
Cache global Sim Sim (~/.cache/pip) Sim (~/.npm)
Vendor mode Sim (go mod vendor) Não nativo Sim (node_modules)

Conclusão

Go Modules resolveu definitivamente o problema de dependências no Go. É simples, integrado ao toolchain, e “apenas funciona”. Se você ainda está usando dep ou GOPATH, migre — não há razão para não usar.

O fluxo de trabalho básico é: go mod init, importe os packages, go mod tidy, commit. O Go cuida do resto.

Caso eu tenha falado alguma besteira, por favor, agradecerei correções e sugestões.