Menu

go mod init e módulos Go: go.mod, go get e go mod tidy

Como os módulos Go funcionam: criar um com go mod init, escolher o caminho do módulo, adicionar dependências com go get, arrumar com go mod tidy, para que serve o go.sum e replace para desenvolvimento local.

Esta página tem editores executáveis - edite, execute e veja a saída na hora.

Um módulo é uma árvore de diretórios de pacotes Go com um arquivo go.mod na raiz. O go.mod dá nome ao módulo e lista as versões de todos os outros módulos dos quais ele depende. Você cria um com go mod init:

mkdir myapp
cd myapp
go mod init example.com/myapp
go: creating new go.mod: module example.com/myapp

O go.mod resultante:

module example.com/myapp

go 1.24.5

Isso basta para compilar. Todo projeto Go desde o Go 1.16 é um módulo, e go build, go run . e go test se recusam a funcionar sem um:

go: go.mod file not found in current directory or any parent directory; see 'go help modules'

Escolhendo o caminho do módulo

O caminho do módulo é o prefixo de todo caminho de import dentro do módulo. Com o módulo example.com/myapp, um pacote no diretório internal/store é importado como example.com/myapp/internal/store.

SituaçãoCaminho do módulo
Código hospedado no GitHub que outros podem importargithub.com/yourname/project
Código da sua empresayourcompany.com/project ou a URL do repositório
Um programa privado ou um exercícioexample.com/myapp ou só myapp
Versão 2 ou posterior de um módulo publicadogithub.com/yourname/project/v2

Para uma biblioteca, o caminho precisa bater com o lugar onde o código está, porque o go get o usa para encontrar o repositório. Para um programa que só você executa, o caminho é só um nome. Evite uma palavra única igual a um pacote da biblioteca padrão, como go mod init fmt ou go mod init strings: o build então falha com ambiguous import: found package fmt in multiple modules.

Executar go mod init sem argumento falha fora do antigo layout do GOPATH:

go: cannot determine module path for source directory /home/ana/myapp (outside GOPATH, module path must be specified)

Passe um caminho.

Adicionando dependências

Escreva o import e deixe o Go buscá-lo. Suponha que main.go importa github.com/google/uuid. Compilar antes de o módulo saber dele dá uma instrução clara:

main.go:6:2: no required module provides package github.com/google/uuid; to add it:
	go get github.com/google/uuid

Qualquer um dos comandos resolve:

go get github.com/google/uuid
# or, to sync go.mod with every import in the module:
go mod tidy

O go get informa o que mudou:

go: downloading github.com/google/uuid v1.6.0
go: added github.com/google/uuid v1.6.0

O go mod tidy informa como resolveu o import:

go: finding module for package github.com/google/uuid
go: downloading github.com/google/uuid v1.6.0
go: found github.com/google/uuid in github.com/google/uuid v1.6.0

O go.mod agora tem uma linha require:

module example.com/myapp

go 1.24.5

require github.com/google/uuid v1.6.0

go get com versões

ComandoEfeito
go get pkgadiciona pkg na última versão lançada, ou mantém a versão atual se já for requisito
go get pkg@v1.5.0usa exatamente a v1.5.0 (atualiza ou volta a versão)
go get pkg@latestpassa para a última versão lançada
go get pkg@abc1234usa um commit específico (registrado como pseudo-versão)
go get -u ./...atualiza todas as dependências para a última versão minor ou patch
go get -u=patch ./...atualiza só para as últimas versões patch
go get pkg@noneremove o requisito
go get go@1.24eleva a versão mínima do Go do módulo

O go get altera o go.mod. Ele não compila nem instala mais programas; desde o Go 1.18 isso é trabalho do go install pkg@version.

Dependências indiretas

Requisitos marcados com // indirect são módulos que o seu código não importa diretamente, mas de que o build precisa. Desde o Go 1.17, o go.mod lista todo módulo que fornece um pacote ao build, então as dependências das suas dependências aparecem aqui com essa marca. O go mod tidy gerencia essas marcas; você não as acrescenta.

go mod tidy

Execute go mod tidy sempre que acrescentar ou remover imports. Ele:

  • acrescenta requisitos para pacotes importados que estão faltando,
  • remove requisitos que nada importa mais,
  • acrescenta as entradas de go.sum de que o build precisa e descarta as antigas.

Ele olha todos os pacotes do módulo, incluindo testes e todas as combinações de build tags, então às vezes mantém uma dependência que você não vê em uso na sua plataforma. Executar go mod tidy antes de cada commit, e verificar no CI que ele não gera diferença, mantém o go.mod honesto.

go.sum

O go.sum registra um hash para cada versão de módulo que o build usa:

github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=

A primeira linha é o hash dos arquivos do módulo, a segunda só do go.mod dele. Quando o comando go baixa um módulo, ele confere o hash com o go.sum e com o banco de checksums público (sum.golang.org), então uma versão adulterada ou alterada em silêncio falha no build. Commite o go.sum junto com o go.mod, e nunca o edite à mão.

Como o Go escolhe as versões

O Go usa seleção de versão mínima (minimal version selection). Cada módulo lista a versão mínima de cada dependência de que precisa, e o build usa a maior dessas mínimas, nunca algo mais novo. Se o seu módulo exige uuid v1.5.0 e uma dependência exige uuid v1.6.0, o build usa a v1.6.0, mesmo que exista a v1.7.0. Nada é atualizado a menos que alguém peça com go get.

A consequência é que os builds são reproduzíveis sem um arquivo de lock: o go.mod mais o grafo de dependências determinam todas as versões. go list -m all imprime o resultado:

go list -m all
example.com/myapp
github.com/google/uuid v1.6.0

Versões major

Um módulo na v2 ou acima precisa incluir a versão major no caminho: github.com/yourname/project/v2. O caminho de import muda junto, então project e project/v2 são módulos diferentes e podem estar os dois no mesmo build. Essa é a regra do Go para mudanças incompatíveis, e é por isso que você vê imports como github.com/jackc/pgx/v5.

replace: trabalhando em uma dependência localmente

Para testar mudanças em uma dependência antes de publicá-las, aponte o caminho dela para um diretório local:

module example.com/myapp

go 1.24.5

require example.com/mylib v1.2.0

replace example.com/mylib => ../mylib

Ou pela linha de comando:

go mod edit -replace example.com/mylib=../mylib
go mod tidy

O diretório precisa ter o seu próprio go.mod. O replace só vale quando este módulo é compilado diretamente, não quando outra pessoa depende dele, então lembre de removê-lo antes de criar a tag de uma versão.

Para editar vários módulos ao mesmo tempo sem mexer nos go.mod deles, o Go 1.18 trouxe os workspaces:

go work init . ../mylib

Isso grava um arquivo go.work que faz o mylib local ter prioridade. Mantenha o go.work fora do controle de versão, a menos que o time inteiro use o mesmo layout.

Dependências de ferramentas (Go 1.24)

O Go 1.24 trouxe a diretiva tool, para que geradores de código e linters tenham versão no go.mod em vez de serem instalados globalmente:

go get -tool golang.org/x/tools/cmd/stringer
go tool stringer -type=Color

func init é outra coisa

Buscas por "golang init" muitas vezes se referem à função init, que não tem relação com go mod init. Qualquer pacote pode declarar func init(). Ela não recebe argumentos, não pode ser chamada pelo seu código e executa uma vez, automaticamente, depois que as variáveis de nível de pacote são definidas e antes do main:

Um arquivo pode ter várias funções init, e elas executam na ordem em que aparecem. Os pacotes importados terminam a própria inicialização primeiro. Mantenha o init pequeno: trabalho que pode falhar é mais fácil de tratar e testar como uma função comum chamada a partir do main.

Módulos privados e proxies

Por padrão, o go baixa módulos pelo proxy.golang.org. Esse proxy não enxerga repositórios privados, então diga ao Go quais caminhos são privados:

go env -w GOPRIVATE=github.com/yourcompany/*

Módulos que casam com GOPRIVATE são buscados direto no repositório com as suas credenciais do git e pulam o banco de checksums.

Perguntas frequentes

O que o go mod init faz?

Ele cria um arquivo go.mod no diretório atual, o que torna esse diretório a raiz de um módulo. go mod init example.com/myapp grava o caminho do módulo e a versão do Go:

module example.com/myapp

go 1.24.5

Execute uma vez por projeto, antes de go build ou go get.

O que usar como caminho do módulo no go mod init?

O endereço de onde o código será baixado se outras pessoas o importarem, normalmente o caminho do repositório: go mod init github.com/yourname/project. Para um programa que ninguém vai importar, qualquer nome serve (go mod init myapp), mas um caminho com ponto, no estilo de domínio, como example.com/myapp, evita conflito com nomes de pacotes da biblioteca padrão.

Qual a diferença entre go get e go mod tidy?

go get pkg@version adiciona uma dependência ou muda a versão dela. go mod tidy lê os seus arquivos-fonte, acrescenta qualquer módulo de que os seus imports precisam e que falta no go.mod, remove requisitos que nada importa e atualiza o go.sum. Um fluxo comum é escrever o import e depois executar go mod tidy.

Devo commitar o go.sum?

Sim. O go.sum guarda hashes criptográficos de toda versão de módulo que o seu build usa. Commitá-lo permite que o comando go verifique se todo mundo baixa dependências idênticas byte a byte. Nunca o edite à mão; o go mod tidy cuida dele.

"golang init" é o mesmo que go mod init?

Não, são coisas diferentes que compartilham uma palavra. go mod init é um comando de terminal que cria o go.mod. func init() é uma função que você escreve no código Go; ela executa automaticamente uma vez, antes do main, depois que as variáveis do pacote são inicializadas.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR