Building and Consuming Custom Packages in Go: A Complete Guide

ansu jain
4 min readMar 2, 2023

--

Go makes it easy to create and use packages. In this tutorial, we’ll create a simple package that uses a third-party dependency and learn how to use it in a new project.

Prerequisites

Before we get started, make sure you have the following:

  • Go installed on your machine
  • Basic knowledge of Go programming language

Step 1: Setting up the Project

To create a new package, create a new directory for your project. For this tutorial, we’ll name it myconfig.

mkdir myconfig

Next, navigate to the myconfig directory and initialize it as a Go module:

cd myconfig
go mod init github.com/<your_username>/myconfig

This will create a go.mod file in the myconfig directory.

Step 2: Adding a Third-Party Dependency

In this tutorial, we’ll use the Viper package as a third-party dependency. Viper is a popular configuration library for Go that allows you to read and write config files in various formats.

To add the Viper package to our project, we’ll modify the go.mod file in our myconfig directory:

module github.com/<your_username>/myconfig

go 1.16

require (
github.com/spf13/viper v1.9.0
)

Run the following command to download the Viper package:

go get github.com/spf13/viper

This will download the Viper package and its dependencies to your $GOPATH/pkg/mod directory.

Step 3: Writing the Package Code

Let’s write some code for our package. In this tutorial, we’ll create a config package that initializes a Viper configuration object and provides a utility function to read a configuration file.

Create a new file named config.go in the myconfig directory:

package config

import (
"fmt"
"github.com/spf13/viper"
)

func ReadConfig(configFilePath string) error {
// Initialize a new viper configuration object
viper.SetConfigFile(configFilePath)
err := viper.ReadInConfig()
if err != nil {
return fmt.Errorf("error reading config file: %s", err)
}
return nil
}

The ReadConfig function initializes a new Viper configuration object and reads the configuration file specified by the configFilePath parameter. If an error occurs while reading the configuration file, the function returns an error.

Step 4: Building the Package

To build our package, we’ll run the following command in the myconfig directory:

go build

This will create a myconfig.a file in the myconfig directory.

Step 5: Pushing the Package to GitHub

To make our package available to others, we’ll push it to GitHub.

  1. Create a new repository on GitHub named myconfig.
  2. In the myconfig directory, initialize the Git repository and commit our changes:
git init
git add .
git commit -m "Initial commit"

3.Add the remote origin for the repository and push our changes:

git remote add origin https://github.com/<your_username>/myconfig.git
git push -u origin master

Let’s understand your pkg through this diagram:

This diagram shows that the module name in the go.mod file is github.com/<your_username>/myconfig. The file includes a list of dependencies that includes Viper (G), which specifies the version of Viper to use (J).

Using Your Package in a New Go Project

Finally we created a custom package called myconfig that uses a third-party package called viper to read and parse configuration files.

In this section, we will show how to use this custom package in a new Go project.

To use our custom package, we need to import it into our new project. To do this, we will use the go get command to download the package from the GitHub repository where we pushed it in the previous section.

go get github.com/<your_username>/myconfig

After running this command, we can use our custom package in our new project by importing it into our code:

import (
"fmt"

"github.com/<your_username>/myconfig"
)

We can now use the functions and types defined in our custom package, including the GetConfig function that we created to read and parse configuration files using viper.

func main() {
// read configuration file
config, err := myconfig.ReadConfig("config.yaml")
if err != nil {
fmt.Println("Error reading config file:", err)
return
}

// use configuration values
dbHost := config.GetString("db.host")
dbPort := config.GetInt("db.port")
dbUser := config.GetString("db.user")
dbPassword := config.GetString("db.password")

// do something with database connection information...
}

Note that because our custom package has a dependency on viper, any project that uses our package will also have access to the viper package and its functionality.

Conclusion

Creating custom packages can be a great way to share and reuse code across multiple projects. By leveraging Go’s built-in package system and third-party packages, we can create powerful and flexible packages that can be used in a wide variety of projects.

I hope you found this article helpful . If you enjoyed reading this, please like the article and consider following me for more programming tutorials.

--

--