A Barebones Introduction To Go Modules
Tags: beginners, go, learning
Published: 2020-03-22 08:24:50

![Go mascot image](https://res.cloudinary.com/practicaldev/image/fetch/s--5fRsTMnS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/whm3oezk396jxn6di1h6.png)

I recently started learning golang and as with any language you're picking up for the first time, I had difficulty understanding some concepts. Coming from the world of JavaScript, installing packages, module management, and general code organization was fairly easy to grasp, however, I wasn't ready for what go had in stock. After doing some research, I found out about go modules, GOPATH, GOROOT, and some other crap I didn't understand. 

Basically, local and 3rd party packages in go weren't very easy to work with as your code has to be in some specific location to be able to install dependencies, but if you're learning go in 2020 you're in luck because since go v1.11, you can use go modules, which is the new dependency management for go.

A **module** is a collection of go packages that reside within a directory that has the file `go.mod` at its root. In essence, a project directory is a module if it has `go.mod` at the top level just like you have a `package.json` in a JavaScript project. A **package**, on the other hand, is a collection of go source files that exist in the same directory. Functions, types, variables, and constants are visible to all files within a package, provided they're **capitalized**.

You can organize your reusable code into its own package and then import anywhere you want to use it. To setup go modules in your project directory, simply run `go mod init <repository url>`. This would create a `go.mod` and a `go.sum` file where you can manage your dependencies. Visit the [official docs](https://blog.golang.org/using-go-modules) to dive deeper. You now can now easily import your local and 3rd party packages without worrying about $GOPATH and whatnot.

>**NOTE**: To use go modules, your project directory must be outside the GOPATH. Go automatically disables go modules when inside GOPATH.

Let's look at a simple example for you to picture this concept clearly. Say you have a project folder named `awesome-cli` with the following structure.
```
awesome-cli ---
              |
             cli ---
                   |
                   cli.go
             config ---
                      |
                      database_config.go
             utils ---
                     |
                     parser.go
                     database.go
             go.mod
             go.sum
             main.go
            .gitignore
             README.md
             Makefile
             
```
To initialize go modules in the project folder, you'd run `go mod innit github.com/<username>/awesome-cli`. Now if you want to import a `Parser` function from `utils/parser.go` into your `cli.go` file, it would look like:

cli.go
```go
package main

import (
    "fmt"
    "github.com/<username>/awesome-go/utils"
)

func main() {
   // use parser function
   parsedArgument, err := utils.Parser(arg)
}
```

parser.go
```go
package utils

func Parser(arg string) (parsedArgument, error) {
   // do something
}
```

Notice that the `Parser` function is capitalized, this is because named exports are capitalized in go. Also, anyone can import this module using the url provided and you can import packages from other repositories with `go get`.

This is a very low-level dive into go modules for a beginner. You can look into the go docs for more advanced concepts.