| <!--{ |
| "Title": "Managing dependencies" |
| }--> |
| |
| When your code uses external packages, those packages (distributed as modules) |
| become dependencies. Over time, you may need to upgrade them or replace them. Go |
| provides dependency management tools that help you keep your Go applications |
| secure as you incorporate external dependencies. |
| |
| This topic describes how to perform tasks to manage dependencies you take on in |
| your code. You can perform most of these with Go tools. This topic also |
| describes how to perform a few other dependency-related tasks you might find |
| useful. |
| |
| **See also** |
| |
| * If you're new to working with dependencies as modules, take a look at the |
| [Getting started tutorial](/doc/tutorial/getting-started) |
| for a brief introduction. |
| * Using the `go` command to manage dependencies helps ensure that your |
| requirements remain consistent and the content of your go.mod file is valid. |
| For reference on the commands, see [Command go](/cmd/go/). |
| You can also get help from the command line by typing `go help` |
| _command-name_, as with `go help mod tidy`. |
| * Go commands you use to make dependency changes edit your go.mod file. For |
| more about the contents of the file, see [go.mod file reference](/doc/modules/gomod-ref). |
| * Making your editor or IDE aware of Go modules can make the work of managing |
| them easier. For more on editors that support Go, see [Editor plugins and |
| IDEs](/doc/editors.html). |
| * This topic doesn't describe how to develop, publish, and version modules for |
| others to use. For more on that, see [Developing and publishing |
| modules](developing). |
| |
| ## Workflow for using and managing dependencies {#workflow} |
| |
| You can get and use useful packages with Go tools. On |
| [pkg.go.dev](https://pkg.go.dev), you can search for packages you might find |
| useful, then use the `go` command to import those packages into your own code to |
| call their functions. |
| |
| The following lists the most common dependency management steps. For more about |
| each, see the sections in this topic. |
| |
| 1. [Locate useful packages](#locating_packages) on [pkg.go.dev](https://pkg.go.dev). |
| 1. [Import the packages](#locating_packages) you want in your code. |
| 1. Add your code to a module for dependency tracking (if it isn't in a module |
| already). See [Enabling dependency tracking](#enable_tracking) |
| 1. [Add external packages as dependencies](#adding_dependency) so you can manage |
| them. |
| 1. [Upgrade or downgrade dependency versions](#upgrading) as needed over time. |
| |
| ## Managing dependencies as modules {#modules} |
| |
| In Go, you manage dependencies as modules that contain the packages you import. |
| This process is supported by: |
| |
| * A **decentralized system for publishing** modules and retrieving their code. |
| Developers make their modules available for other developers to use from |
| their own repository and publish with a version number. |
| * A **package search engine** and documentation browser (pkg.go.dev) at which |
| you can find modules. See [Locating and importing useful packages](#locating_packages). |
| * A module **version numbering convention** to help you understand a module's |
| stability and backward compatibility guarantees. See [Module version |
| numbering](version-numbers). |
| * **Go tools** that make it easier for you to manage dependencies, including |
| getting a module's source, upgrading, and so on. See sections of this topic |
| for more. |
| |
| ## Locating and importing useful packages {#locating_packages} |
| |
| You can search [pkg.go.dev](https://pkg.go.dev) to find packages with functions |
| you might find useful. |
| |
| When you've found a package you want to use in your code, locate the package |
| path at the top of the page and click the Copy path button to copy the path to |
| your clipboard. In your own code, paste the path into an import statement, as in |
| the following example: |
| |
| ``` |
| import "rsc.io/quote" |
| ``` |
| |
| After your code imports the package, enable dependency tracking and get the |
| package's code to compile with. For more, see [Enabling dependency tracking in |
| your code](#enable_tracking) and [Adding a dependency](#adding_dependency). |
| |
| ## Enabling dependency tracking in your code {#enable_tracking} |
| |
| To track and manage the dependencies you add, you begin by putting your code in |
| its own module. This creates a go.mod file at the root of your source tree. |
| Dependencies you add will be listed in that file. |
| |
| To add your code to its own module, use the |
| [`go mod init` command](/ref/mod#go-mod-init). For example, from the command |
| line, change to your code's root directory, then run the command as in the |
| following example: |
| |
| ``` |
| $ go mod init example/mymodule |
| ``` |
| |
| The `go mod init` command's argument is your module's module path. If possible, |
| the module path should be the repository location of your source code. |
| |
| If at first you don't know the module's eventual repository location, use a |
| safe substitute. This might be the name of a domain you own or another name you |
| control (such as your company name), along with a path following from the |
| module's name or source directory. For more, see |
| [Naming a module](#naming_module). |
| |
| As you use Go tools to manage dependencies, the tools update the go.mod file so |
| that it maintains a current list of your dependencies. |
| |
| When you add dependencies, Go tools also create a go.sum file that contains |
| checksums of modules you depend on. Go uses this to verify the integrity of |
| downloaded module files, especially for other developers working on your |
| project. |
| |
| Include the go.mod and go.sum files in your repository with your code. |
| |
| See the [go.mod reference](/doc/modules/gomod-ref) for more. |
| |
| ## Naming a module {#naming_module} |
| |
| When you run `go mod init` to create a module for tracking dependencies, you |
| specify a module path that serves as the module's name. The module path |
| becomes the import path prefix for packages in the module. Be sure to specify |
| a module path that won't conflict with the module path of other modules. |
| |
| At a minimum, a module path need only indicate something about its origin, such |
| as a company or author or owner name. But the path might also be more |
| descriptive about what the module is or does. |
| |
| The module path is typically of the following form: |
| |
| ``` |
| <prefix>/<descriptive-text> |
| ``` |
| |
| * The _prefix_ is typically a string that partially describes the module, such |
| as a string that describes its origin. This might be: |
| |
| * The location of the repository where Go tools can find the module's source |
| code (required if you're publishing the module). |
| |
| For example, it might be `github.com/<project-name>/`. |
| |
| Use this best practice if you think you might publish the module for |
| others to use. For more about publishing, see |
| [Developing and publishing modules](/doc/modules/developing). |
| |
| * A name you control. |
| |
| If you're not using a repository name, be sure to choose a prefix that |
| you're confident won't be used by others. A good choice is your |
| company's name. Avoid common terms such as `widgets`, `utilities`, or |
| `app`. |
| |
| * For the _descriptive text_, a good choice would be a project name. Remember |
| that package names carry most of the weight of describing functionality. |
| The module path creates a namespace for those package names. |
| |
| **Reserved module path prefixes** |
| |
| Go guarantees that the following strings won't be used in package names. |
| |
| - `test` -- You can use `test` as a module path prefix for a module whose code |
| is designed to locally test functions in another module. |
| |
| Use the `test` path prefix for modules that are created as part of a test. |
| For example, your test itself might run `go mod init test` and then set up |
| that module in some particular way in order to test with a Go source code |
| analysis tool. |
| |
| - `example` -- Used as a module path prefix in some Go documentation, such as |
| in tutorials where you're creating a module just to track dependencies. |
| |
| Note that Go documentation also uses `example.com` to illustrate when the |
| example might be a published module. |
| |
| ## Adding a dependency {#adding_dependency} |
| |
| Once you're importing packages from a published module, you can add that module |
| to manage as a dependency by using the [`go get` |
| command](/cmd/go/#hdr-Add_dependencies_to_current_module_and_install_them). |
| |
| The command does the following: |
| |
| * If needed, it adds `require` directives to your go.mod file for modules |
| needed to build packages named on the command line. A `require` directive |
| tracks the minimum version of a module that your module depends on. See the |
| [go.mod reference](/doc/modules/gomod-ref) for more. |
| * If needed, it downloads module source code so you can compile packages that |
| depend on them. It can download modules from a module proxy like |
| proxy.golang.org or directly from version control repositories. The source |
| is cached locally. |
| |
| You can set the location from which Go tools download modules. For more, see |
| [Specifying a module proxy server](#proxy_server). |
| |
| The following describes a few examples. |
| |
| * To add all dependencies for a package in your module, run a command like the |
| one below ("." refers to the package in the current directory): |
| |
| ``` |
| $ go get . |
| ``` |
| |
| * To add a specific dependency, specify its module path as an argument to the |
| command. |
| |
| ``` |
| $ go get example.com/theirmodule |
| ``` |
| |
| The command also authenticates each module it downloads. This ensures that it's |
| unchanged from when the module was published. If the module has changed since it |
| was published -- for example, the developer changed the contents of the commit |
| -- Go tools will present a security error. This authentication check protects |
| you from modules that might have been tampered with. |
| |
| ## Getting a specific dependency version {#getting_version} |
| |
| You can get a specific version of a dependency module by specifying its version |
| in the `go get` command. The command updates the `require` directive in your |
| go.mod file (though you can also update that manually). |
| |
| You might want to do this if: |
| |
| * You want to get a specific pre-release version of a module to try out. |
| * You've discovered that the version you're currently requiring isn't working |
| for you, so you want to get a version you know you can rely on. |
| * You want to upgrade or downgrade a module you're already requiring. |
| |
| Here are examples for using the [`go get` |
| command](/ref/mod#go-get): |
| |
| * To get a specific numbered version, append the module path with an @ sign |
| followed by the version you want: |
| |
| ``` |
| $ go get example.com/theirmodule@v1.3.4 |
| ``` |
| |
| * To get the latest version, append the module path with `@latest`: |
| |
| ``` |
| $ go get example.com/theirmodule@latest |
| ``` |
| |
| The following go.mod file `require` directive example (see the [go.mod |
| reference](/doc/modules/gomod-ref) for more) illustrates how to require a specific version |
| number: |
| |
| ``` |
| require example.com/theirmodule v1.3.4 |
| ``` |
| |
| ## Discovering available updates {#discovering_updates} |
| |
| You can check to see if there are newer versions of dependencies you're already |
| using in your current module. Use the `go list` command to display a list of |
| your module's dependencies, along with the latest version available for that |
| module. Once you've discovered available upgrades, you can try them out with your |
| code to decide whether or not to upgrade to new versions. |
| |
| For more about the `go list` command, see [`go list -m`](/ref/mod#go-list-m). |
| |
| Here are a couple of examples. |
| |
| * List all of the modules that are dependencies of your current module, |
| along with the latest version available for each: |
| |
| ``` |
| $ go list -m -u all |
| ``` |
| |
| * Display the latest version available for a specific module: |
| |
| ``` |
| $ go list -m -u example.com/theirmodule |
| ``` |
| |
| ## Upgrading or downgrading a dependency {#upgrading} |
| |
| You can upgrade or downgrade a dependency module by using Go tools to discover |
| available versions, then add a different version as a dependency. |
| |
| 1. To discover new versions use the `go list` command as described in |
| [Discovering available updates](#discovering_updates). |
| |
| 1. To add a particular version as a dependency, use the `go get` command as |
| described in [Getting a specific dependency version](#getting_version). |
| |
| ## Synchronizing your code's dependencies {#synchronizing} |
| |
| You can ensure that you're managing dependencies for all of your code's imported |
| packages while also removing dependencies for packages you're no longer |
| importing. |
| |
| This can be useful when you've been making changes to your code and |
| dependencies, possibly creating a collection of managed dependencies and |
| downloaded modules that no longer match the collection specifically required by |
| the packages imported in your code. |
| |
| To keep your managed dependency set tidy, use the `go mod tidy` command. Using |
| the set of packages imported in your code, this command edits your go.mod file |
| to add modules that are necessary but missing. It also removes unused modules |
| that don't provide any relevant packages. |
| |
| The command has no arguments except for one flag, -v, that prints information |
| about removed modules. |
| |
| ``` |
| $ go mod tidy |
| ``` |
| |
| ## Developing and testing against unpublished module code {#unpublished} |
| |
| You can specify that your code should use dependency modules that may not be |
| published. The code for these modules might be in their respective repositories, |
| in a fork of those repositories, or on a drive with the current module that |
| consumes them. |
| |
| You might want to do this when: |
| |
| * You want to make your own changes to an external module's code, such as |
| after forking and/or cloning it. For example, you might want to prepare a |
| fix to the module, then send it as a pull request to the module's developer. |
| * You're building a new module and haven't yet published it, so it's |
| unavailable on a repository where the `go get` command can reach it. |
| |
| ### Requiring module code in a local directory {#local_directory} |
| |
| You can specify that the code for a required module is on the same local drive |
| as the code that requires it. You might find this useful when you are: |
| |
| * Developing your own separate module and want to test from the current module. |
| * Fixing issues in or adding features to an external module and want to test |
| from the current module. (Note that you can also require the external module |
| from your own fork of its repository. For more, see [Requiring external |
| module code from your own repository fork](#external_fork).) |
| |
| To tell Go commands to use the local copy of the module's code, use the |
| `replace` directive in your go.mod file to replace the module path given in a |
| `require` directive. See the [go.mod reference](/doc/modules/gomod-ref) for |
| more about directives. |
| |
| In the following go.mod file example, the current module requires the external |
| module `example.com/theirmodule`, with a nonexistent version number |
| (`v0.0.0-unpublished`) used to ensure the replacement works correctly. The |
| `replace` directive then replaces the original module path with |
| `../theirmodule`, a directory that is at the same level as the current module's |
| directory. |
| |
| ``` |
| module example.com/mymodule |
| |
| go 1.23.0 |
| |
| require example.com/theirmodule v0.0.0-unpublished |
| |
| replace example.com/theirmodule v0.0.0-unpublished => ../theirmodule |
| ``` |
| |
| When setting up a `require`/`replace` pair, use the |
| [`go mod edit`](/ref/mod#go-mod-edit) and [`go get`](/ref/mod#go-get) commands |
| to ensure that requirements described by the file remain consistent: |
| |
| ``` |
| $ go mod edit -replace=example.com/theirmodule@v0.0.0-unpublished=../theirmodule |
| $ go get example.com/theirmodule@v0.0.0-unpublished |
| ``` |
| |
| **Note:** When you use the replace directive, Go tools don't authenticate |
| external modules as described in [Adding a dependency](#adding_dependency). |
| |
| For more about version numbers, see [Module version numbering](/doc/modules/version-numbers). |
| |
| ### Requiring external module code from your own repository fork {#external_fork} |
| |
| When you have forked an external module's repository (such as to fix an issue in |
| the module's code or to add a feature), you can have Go tools use your fork for |
| the module's source. This can be useful for testing changes from your own code. |
| (Note that you can also require the module code in a directory that's on the |
| local drive with the module that requires it. For more, see [Requiring module |
| code in a local directory](#local_directory).) |
| |
| You do this by using a `replace` directive in your go.mod file to replace the |
| external module's original module path with a path to the fork in your |
| repository. This directs Go tools to use the replacement path (the fork's |
| location) when compiling, for example, while allowing you to leave `import` |
| statements unchanged from the original module path. |
| |
| For more about the `replace` directive, see the [go.mod file |
| reference](gomod-ref). |
| |
| In the following go.mod file example, the current module requires the external |
| module `example.com/theirmodule`. The `replace` directive then replaces the |
| original module path with `example.com/myfork/theirmodule`, a fork of the |
| module's own repository. |
| |
| ``` |
| module example.com/mymodule |
| |
| go 1.23.0 |
| |
| require example.com/theirmodule v1.2.3 |
| |
| replace example.com/theirmodule v1.2.3 => example.com/myfork/theirmodule v1.2.3-fixed |
| ``` |
| |
| When setting up a `require`/`replace` pair, use Go tool commands to ensure that |
| requirements described by the file remain consistent. Use the [`go |
| list`](/ref/mod#go-list-m) command to get the version in use by the current |
| module. Then use the [`go mod edit`](/ref/mod#go-mod-edit) command to replace |
| the required module with the fork: |
| |
| ``` |
| $ go list -m example.com/theirmodule |
| example.com/theirmodule v1.2.3 |
| $ go mod edit -replace=example.com/theirmodule@v1.2.3=example.com/myfork/theirmodule@v1.2.3-fixed |
| ``` |
| |
| **Note:** When you use the `replace` directive, Go tools don't authenticate |
| external modules as described in [Adding a dependency](#adding_dependency). |
| |
| For more about version numbers, see [Module version numbering](/doc/modules/version-numbers). |
| |
| ## Getting a specific commit using a repository identifier {#repo_identifier} |
| |
| You can use the `go get` command to add unpublished code for a module from a |
| specific commit in its repository. |
| |
| To do this, you use the `go get` command, specifying the code you want with an |
| `@` sign. When you use `go get`, the command will add to your go.mod file a |
| `require` directive that requires the external module, using a pseudo-version |
| number based on details about the commit. |
| |
| The following examples provide a few illustrations. These are based on a module |
| whose source is in a git repository. |
| |
| * To get the module at a specific commit, append the form @<em>commithash</em>: |
| |
| ``` |
| $ go get example.com/theirmodule@4cf76c2 |
| ``` |
| |
| * To get the module at a specific branch, append the form @<em>branchname</em>: |
| |
| ``` |
| $ go get example.com/theirmodule@bugfixes |
| ``` |
| |
| ## Removing a dependency {#removing_dependency} |
| |
| When your code no longer uses any packages in a module, you can stop tracking |
| the module as a dependency. |
| |
| To stop tracking all unused modules, run the [`go mod tidy` |
| command](/ref/mod#go-mod-tidy). This command may also add missing dependencies |
| needed to build packages in your module. |
| |
| ``` |
| $ go mod tidy |
| ``` |
| |
| To remove a specific dependency, use the [`go get` |
| command](/ref/mod#go-get), specifying the module's module path and appending |
| `@none`, as in the following example: |
| |
| ``` |
| $ go get example.com/theirmodule@none |
| ``` |
| |
| The `go get` command will also downgrade or remove other dependencies that |
| depend on the removed module. |
| |
| ## Tool dependencies {#tools} |
| |
| Tool dependencies let you manage developer tools that are written in Go and used |
| when working on your module. For example, you might use |
| [`stringer`](https://pkg.go.dev/golang.org/x/tools/cmd/stringer) with [`go |
| generate`](/blog/generate), or a specific linter or formatter as part of |
| preparing your change for submission. |
| |
| In Go 1.24 and above, you can add a tool dependency with: |
| |
| ``` |
| $ go get -tool golang.org/x/tools/cmd/stringer |
| ``` |
| |
| This will add a [`tool` directive](/ref/mod/#go-mod-file-tool) to your `go.mod` file, and ensure the |
| necessary require directives are present. Once this directive is added you can |
| run the tool by passing the last [non-major-version](/ref/mod#major-version-suffixes) |
| component of the tool's import path to `go tool`: |
| |
| ``` |
| $ go tool stringer |
| ``` |
| |
| In the case that multiple tools share the last path fragment, or the path fragment |
| matches one of the tools shipped with the Go distribution, you must pass the full |
| package path instead: |
| |
| ``` |
| $ go tool golang.org/x/tools/cmd/stringer |
| ``` |
| |
| To see a list of all tools currently available, run `go tool` with no arguments: |
| |
| ``` |
| $ go tool |
| ``` |
| |
| You can manually add a `tool` directive to your `go.mod`, but you must ensure |
| that there is a `require` directive for the module that defines the tool. The |
| easiest way to add any missing `require` directives is to run: |
| |
| ``` |
| $ go mod tidy |
| ``` |
| |
| Requirements needed to satisfy tool dependencies behave like any other |
| requirements in your [module graph](/ref/mod#glos-module-graph). They |
| participate in [minimal version selection](/ref/mod#minimal-version-selection) |
| and respect `require`, `replace` and `exclude` directives. Due to module |
| pruning, when you depend on a module that itself has a tool dependency, |
| requirements that exist just to satisfy that tool dependency do not usually |
| become requirements of your module. |
| |
| The `tool` [meta-pattern](/cmd/go#hdr-Package_lists_and_patterns) provides a way to perform operations on all tools simultaneously. For example you can upgrade all tools with `go get -u tool`, or install them all to $GOBIN with `go install tool`. |
| |
| In Go versions before 1.24, you can acheive something similar to a `tool` |
| directive by adding a blank import to a go file within the module that is |
| excluded from the build using [build |
| constraints](/pkg/go/build/#hdr-Build_Constraints). If you do this, you can then |
| use `go run` with the full package path to run the tool. |
| |
| ## Specifying a module proxy server {#proxy_server} |
| |
| When you use Go tools to work with modules, the tools by default download |
| modules from proxy.golang.org (a public Google-run module mirror) or directly |
| from the module's repository. You can specify that Go tools should instead use |
| another proxy server for downloading and authenticating modules. |
| |
| You might want to do this if you (or your team) have set up or chosen a |
| different module proxy server that you want to use. For example, some set up a |
| module proxy server in order to have greater control over how dependencies are |
| used. |
| |
| To specify another module proxy server for Go tools use, set the `GOPROXY` |
| environment variable to the URL of one or more servers. Go tools will try each |
| URL in the order you specify. By default, `GOPROXY` specifies a public |
| Google-run module proxy first, then direct download from the module's repository |
| (as specified in its module path): |
| |
| ``` |
| GOPROXY="https://proxy.golang.org,direct" |
| ``` |
| |
| For more about the `GOPROXY` environment variable, including values to support |
| other behavior, see the [`go` command |
| reference](/cmd/go/#hdr-Module_downloading_and_verification). |
| |
| You can set the variable to URLs for other module proxy servers, separating URLs |
| with either a comma or a pipe. |
| |
| * When you use a comma, Go tools will try the next URL in the list only if the |
| current URL returns an HTTP 404 or 410. |
| |
| ``` |
| GOPROXY="https://proxy.example.com,https://proxy2.example.com" |
| ``` |
| |
| * When you use a pipe, Go tools will try the next URL in the list regardless |
| of the HTTP error code. |
| |
| ``` |
| GOPROXY="https://proxy.example.com|https://proxy2.example.com" |
| ``` |
| |
| |
| Go modules are frequently developed and distributed on version control servers |
| and module proxies that aren’t available on the public internet. You can set the |
| `GOPRIVATE` environment variable to configure the `go` command |
| to download and build modules from private sources. |
| Then the go command can download and build modules from private sources. |
| |
| The `GOPRIVATE` or `GONOPROXY` environment variables may be set to lists of glob |
| patterns matching module prefixes that are private and should not be requested |
| from any proxy. For example: |
| |
| ``` |
| GOPRIVATE=*.corp.example.com,*.research.example.com |
| ``` |