Working with YAML in Go (Golang) — libraries gopkg.in/yaml.v3 and encoding/json

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Working with YAML in Go (Golang) — library gopkg.in/yaml.v3



YAML (YAML Ain't Markup Language) is a popular data serialization format, often used for configuration files, API descriptions (OpenAPI/Swagger), CI/CD pipelines (GitLab CI, GitHub Actions), and Docker Compose. In the Go (Golang) ecosystem, there is no standard library for working with YAML, so developers use the powerful and stable third-party library gopkg.in/yaml.v3. In this article, we will thoroughly cover how to read, write, and process YAML in Go.



Installing the Library

To get started, add the package to your project:

go get gopkg.in/yaml.v3

Then import it into your code:

import "gopkg.in/yaml.v3"


Basic Structures for Working with YAML

The yaml.v3 library supports:

  • Marshaling (Marshal) — converting Go structures to a YAML string.
  • Unmarshaling (Unmarshal) — parsing a YAML string into a Go structure.
  • Stream parsing (Decoder/Encoder) for working with files.
  • Tags yaml:"fieldname" for configuring field names.


Example 1: Reading YAML from a String

The simplest case is parsing a YAML string into a Go structure:

package main

import ( "fmt" "gopkg.in/yaml.v3")

type Config struct { Server struct { Port int `yaml:"port"` Host string `yaml:"host"` } `yaml:"server"` Database struct { User string `yaml:"user"` Pass string `yaml:"pass"` } `yaml:"database"`}

func main() { yamlData := `server: port: 8080 host: "localhost"database: user: "admin" pass: "secret"` var cfg Config err := yaml.Unmarshal([]byte(yamlData), &cfg) if err != nil { panic(err) } fmt.Printf("Server: %s:%d", cfg.Server.Host, cfg.Server.Port) fmt.Printf("Database: %s", cfg.Database.User)}


Example 2: Writing YAML to a File

To write data to a YAML file, use yaml.Marshal and write to the file system:

package main

import ( "os" "gopkg.in/yaml.v3")

type AppConfig struct { Name string `yaml:"name"` Version string `yaml:"version"` Debug bool `yaml:"debug"`}

func main() { config := AppConfig{ Name: "MyApp", Version: "1.0.0", Debug: true, }

data, err := yaml.Marshal(&config) if err != nil { panic(err) }

err = os.WriteFile("config.yaml", data, 0644) if err != nil { panic(err) } println("File config.yaml created")}


Example 3: Working with Nested and Complex Structures

YAML supports lists, map structures, and deep nesting. Here is an example of parsing a list of servers:

package main

import ( "fmt" "gopkg.in/yaml.v3")

type Service struct { Name string `yaml:"name"` Ports []int `yaml:"ports"` Enabled bool `yaml:"enabled"`}

type Deployment struct { Version string `yaml:"version"` Services []Service `yaml:"services"`}

func main() { input := `version: "2.1"services: - name: web ports: [80, 443] enabled: true - name: api ports: [3000] enabled: false` var dep Deployment if err := yaml.Unmarshal([]byte(input), &dep); err != nil { panic(err) }

for _, s := range dep.Services { fmt.Printf("Service %s: ports %v, enabled: %t", s.Name, s.Ports, s.Enabled) }}


Stream Reading and Writing (Decoder/Encoder)

For working with large files or data streams, use yaml.Decoder and yaml.Encoder:

package main

import ( "

Recommendations