Mapstructure for Go: Complete Guide to Mapping Maps into Structs
What It Is and Why You Need It
The mapstructure library for Go solves one of the most common challenges when working with dynamic data: converting unstructured map[string]interface{} into strongly typed Go structs. In real-world projects, data often arrives as JSON, YAML, TOML, or from external APIs where the structure isn't guaranteed. While the standard encoding/json handles JSON well, when you're dealing with arbitrary maps (e.g., from config files, Redis Hashes, or SQL query results), you need a tool that can map data flexibly and safely.
The core job of mapstructure is to take a map[string]interface{} and populate a struct's fields, automatically converting types, supporting nested structs, slices, pointers, and even custom types. The library shines when parsing configurations where keys might be in snake_case but struct fields are in CamelCase, or when deserializing data from sources that don't follow a standard JSON schema.
The key advantage of mapstructure over manual mapping is its declarative nature. You define a struct with tags, and the library handles recursive traversal, type conversion (e.g., string to int), optional fields, and type mismatch errors. This makes your code cleaner, safer, and significantly reduces boilerplate.
Installation
Use the standard Go package manager to install the library. Make sure you have a module initialized (go mod init).
go get github.com/mitchellh/mapstructure
After running the command, the library will be added to your go.mod and go.sum files. Import it in your code like this:
import "github.com/mitchellh/mapstructure"
The version at the time of writing is v1.5.0. The library has no external dependencies beyond the Go standard library.
Quick Start — Minimal Working Example
Let's create a simple Person struct and convert a map[string]interface{} into an instance of that struct.
package main
import (
"fmt"
"github.com/mitchellh/mapstructure"
)
type Person struct {
Name string
Age int
City string
}
func main() {
input := map[string]interface{}{
"name": "Alice",
"age": 30,
"city": "New York",
}
var person Person
err := mapstructure.Decode(input, &person)
if err != nil {
panic(err)
}
fmt.Printf("Person: %+v\n", person)
// Output: Person: {Name:Alice Age:30 City:New York}
}
As you can see, the map keys automatically matched the struct fields (case-insensitive by default). Even if the key were "AGE", it would still map to the Age field.
Core Methods and Functions
Here are 8 key functions/methods from the mapstructure library. Each method includes its signature, description, and a code example.
1. Decode
Signature: func Decode(input interface{}, output interface{}) error
What it does: The primary function for decoding a map into a struct. It accepts any input (typically map[string]interface{}) and a pointer to the output struct. Returns an error if types are incompatible or another issue occurs.
type Config struct {
Host string
Port int
}
func main() {
data := map[string]interface{}{
"host": "localhost",
"port": 8080,
}
var cfg Config
if err := mapstructure.Decode(data, &cfg); err != nil {
panic(err)
}
fmt.Printf("Config: %+v\n", cfg)
// Output: Config: {Host:localhost Port:8080}
}
Also in library
PDF Generation in C++: Libraries, Tools, and Code Examples
Monitoring TypeScript Applications with Appmetrics
Machine Learning in Kotlin: Overview of KMath, Smile, KotlinDL, and DeepLearning4J Libraries
Cryptography in PHP: Encryption and Hashing (Practical Guide)