Convert Figma logo to code with AI

pelletier logogo-toml

Go library for the TOML file format

1,961
247
1,961
27

Top Related Projects

4,984

TOML parser for Golang with reflection.

30,364

Go configuration with fangs

7,029

YAML support for the Go language.

10,542

A Go port of Ruby's dotenv library (Loads environment variables from .env files)

Golang library for managing configuration data from environment variables

3,102

Mergo: merging Go structs and maps since 2013

Quick Overview

pelletier/go-toml is a Go library for parsing and manipulating TOML (Tom's Obvious, Minimal Language) files. It provides a robust and efficient implementation for working with TOML data in Go applications, supporting both reading and writing TOML files.

Pros

  • Full support for TOML v1.0.0 specification
  • High performance and memory efficiency
  • Extensive API for querying and modifying TOML data
  • Well-maintained with regular updates and bug fixes

Cons

  • Learning curve for complex operations
  • Limited support for older TOML versions
  • Occasional breaking changes between major versions

Code Examples

  1. Parsing a TOML file:
config, err := toml.LoadFile("config.toml")
if err != nil {
    log.Fatal(err)
}
fmt.Println(config.Get("database.server").(string))
  1. Creating and writing a TOML file:
newConfig := toml.NewTable()
newConfig.Set("name", "John Doe")
newConfig.Set("age", 30)

f, err := os.Create("output.toml")
if err != nil {
    log.Fatal(err)
}
defer f.Close()

encoder := toml.NewEncoder(f)
err = encoder.Encode(newConfig)
if err != nil {
    log.Fatal(err)
}
  1. Querying nested TOML data:
tree, _ := toml.Load(`
[fruits]
  [fruits.apple]
    color = "red"
    taste = "sweet"
`)

apple := tree.Get("fruits.apple").(*toml.Tree)
fmt.Println(apple.Get("color").(string)) // Output: red

Getting Started

To use pelletier/go-toml in your Go project:

  1. Install the library:

    go get github.com/pelletier/go-toml/v2
    
  2. Import it in your Go code:

    import "github.com/pelletier/go-toml/v2"
    
  3. Start using the library to parse or create TOML data:

    data, err := toml.Load(`
    [server]
    host = "localhost"
    port = 8080
    `)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(data.Get("server.port").(int64))
    

Competitor Comparisons

4,984

TOML parser for Golang with reflection.

Pros of toml

  • More established and widely used in the Go community
  • Extensive documentation and examples available
  • Supports both encoding and decoding of TOML data

Cons of toml

  • Slightly slower performance compared to go-toml
  • Less frequent updates and maintenance

Code Comparison

go-toml:

config, err := toml.LoadFile("config.toml")
if err != nil {
    log.Fatal(err)
}
value := config.Get("database.server").(string)

toml:

var config struct {
    Database struct {
        Server string `toml:"server"`
    } `toml:"database"`
}
_, err := toml.DecodeFile("config.toml", &config)
if err != nil {
    log.Fatal(err)
}
value := config.Database.Server

Both libraries offer similar functionality for parsing TOML files, but go-toml provides a more flexible API for accessing values, while toml uses struct tags for mapping TOML data to Go structs.

go-toml offers additional features like querying with dotted keys and modifying the parsed tree, making it more versatile for complex configurations. However, toml's approach of using struct tags can lead to more type-safe and idiomatic Go code.

Ultimately, the choice between these libraries depends on specific project requirements, performance needs, and personal preference for API design.

30,364

Go configuration with fangs

Pros of Viper

  • Supports multiple configuration formats (YAML, JSON, TOML, etc.)
  • Offers live watching and automatic reloading of configuration files
  • Provides environment variable support and command-line flag integration

Cons of Viper

  • More complex setup and usage compared to go-toml
  • Larger dependency footprint
  • May be overkill for simple configuration needs

Code Comparison

go-toml:

config, _ := toml.LoadFile("config.toml")
value := config.Get("database.host").(string)

Viper:

viper.SetConfigFile("config.toml")
viper.ReadInConfig()
value := viper.GetString("database.host")

Summary

Viper offers a more comprehensive configuration management solution with support for multiple formats and dynamic reloading. However, it comes with increased complexity and a larger footprint. go-toml is simpler and more lightweight, focusing specifically on TOML parsing. Choose Viper for more advanced configuration needs and go-toml for straightforward TOML handling in Go projects.

7,029

YAML support for the Go language.

Pros of yaml

  • More widely used and established in the Go community
  • Supports both YAML 1.1 and 1.2 specifications
  • Offers more advanced features like custom tags and type-safe unmarshaling

Cons of yaml

  • Generally slower performance compared to go-toml
  • More complex API, which can lead to a steeper learning curve
  • Larger codebase and dependencies

Code Comparison

yaml:

type Config struct {
    Name string `yaml:"name"`
    Age  int    `yaml:"age"`
}

var cfg Config
err := yaml.Unmarshal([]byte(yamlData), &cfg)

go-toml:

type Config struct {
    Name string
    Age  int
}

var cfg Config
err := toml.Unmarshal([]byte(tomlData), &cfg)

Both libraries offer similar unmarshaling capabilities, but yaml requires explicit struct tags for field mapping, while go-toml can infer field names automatically.

yaml provides more flexibility in handling complex data structures and custom types, making it suitable for more advanced use cases. However, go-toml offers a simpler API and better performance for basic configuration needs.

The choice between these libraries depends on the specific requirements of your project, such as the complexity of your data structures, performance needs, and familiarity with YAML or TOML formats.

10,542

A Go port of Ruby's dotenv library (Loads environment variables from .env files)

Pros of godotenv

  • Simpler and more focused on handling .env files
  • Lightweight and easy to integrate into projects
  • Follows the widely-used .env file format standard

Cons of godotenv

  • Limited to .env file format, less versatile than go-toml
  • Lacks advanced features like marshaling/unmarshaling structs
  • No support for writing or modifying configuration files

Code Comparison

godotenv:

import "github.com/joho/godotenv"

err := godotenv.Load()
if err != nil {
    log.Fatal("Error loading .env file")
}

go-toml:

import "github.com/pelletier/go-toml/v2"

config, err := toml.LoadFile("config.toml")
if err != nil {
    log.Fatal(err)
}

Summary

godotenv is a straightforward library for loading environment variables from .env files, making it ideal for simple configuration management. go-toml, on the other hand, offers more comprehensive TOML file handling capabilities, including reading, writing, and manipulating TOML data structures. While godotenv is easier to use for basic .env file operations, go-toml provides greater flexibility and features for working with TOML-formatted configuration files.

Golang library for managing configuration data from environment variables

Pros of envconfig

  • Simpler and more lightweight, focusing solely on environment variable configuration
  • Directly populates struct fields, reducing boilerplate code
  • Supports custom parsing for complex types

Cons of envconfig

  • Limited to environment variables, less flexible for complex configurations
  • Lacks support for hierarchical data structures
  • No built-in file parsing capabilities

Code Comparison

envconfig:

type Config struct {
    Host string `envconfig:"HOST"`
    Port int    `envconfig:"PORT"`
}

var c Config
err := envconfig.Process("myapp", &c)

go-toml:

type Config struct {
    Host string
    Port int
}

var c Config
tree, _ := toml.LoadFile("config.toml")
err := tree.Unmarshal(&c)

Key Differences

  • go-toml is more versatile, supporting TOML file parsing and manipulation
  • envconfig is focused on environment variables, making it simpler for specific use cases
  • go-toml offers more advanced features like querying and modifying TOML data
  • envconfig provides a more straightforward approach for environment-based configuration

Use Case Considerations

  • Choose envconfig for projects primarily using environment variables for configuration
  • Opt for go-toml when dealing with complex, hierarchical configurations or TOML files
  • Consider go-toml for projects requiring both file-based and programmatic configuration management
3,102

Mergo: merging Go structs and maps since 2013

Pros of mergo

  • Focuses on merging Go structs and maps, offering more specialized functionality
  • Provides options for customizing merge behavior, such as overwriting or appending slices
  • Supports deep merging of nested structures

Cons of mergo

  • Limited to merging Go data structures, unlike go-toml's TOML parsing capabilities
  • May require more manual setup for complex merging scenarios
  • Less suitable for configuration file handling compared to go-toml

Code Comparison

mergo:

type Foo struct {
    A string
    B int
}

var src = Foo{A: "one", B: 2}
var dst = Foo{A: "two"}
mergo.Merge(&dst, src)

go-toml:

type Config struct {
    Name string
    Port int
}

var config Config
toml.Unmarshal([]byte(`name = "example"`), &config)

Summary

mergo is specialized for merging Go structs and maps, offering customizable merge options. go-toml focuses on parsing and manipulating TOML configuration files. While mergo provides more control over merging data structures, go-toml is better suited for handling configuration files in the TOML format. The choice between the two depends on the specific use case and data format requirements of your project.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

go-toml v2

Go library for the TOML format.

This library supports TOML v1.1.0.

🐞 Bug Reports

💬 Anything else

Documentation

Full API, examples, and implementation notes are available in the Go documentation.

Go Reference

Import

import "github.com/pelletier/go-toml/v2"

Features

Stdlib behavior

As much as possible, this library is designed to behave similarly as the standard library's encoding/json.

When encoding structs, fields tagged with omitempty are omitted if they are empty. For time.Time, the zero value is considered empty, so timestamps such as created_at or updated_at are not written unless you remove omitempty from the struct tag or use a pointer type (*time.Time).

Performance

While go-toml favors usability, it is written with performance in mind. Most operations should not be shockingly slow. See benchmarks.

Strict mode

Decoder can be set to "strict mode", which makes it error when some parts of the TOML document was not present in the target structure. This is a great way to check for typos. See example in the documentation.

Contextualized errors

When most decoding errors occur, go-toml returns DecodeError, which contains a human readable contextualized version of the error. For example:

1| [server]
2| path = 100
 |        ~~~ cannot decode TOML integer into struct field toml_test.Server.Path of type string
3| port = 50

Local date and time support

TOML supports native local date/times. It allows to represent a given date, time, or date-time without relation to a timezone or offset. To support this use-case, go-toml provides LocalDate, LocalTime, and LocalDateTime. Those types can be transformed to and from time.Time, making them convenient yet unambiguous structures for their respective TOML representation.

Commented config

Since TOML is often used for configuration files, go-toml can emit documents annotated with comments and commented-out values. For example, it can generate the following file:

# Host IP to connect to.
host = '127.0.0.1'
# Port of the remote server.
port = 4242

# Encryption parameters (optional)
# [TLS]
# cipher = 'AEAD-AES128-GCM-SHA256'
# version = 'TLS 1.3'

Getting started

Given the following struct, let's see how to read it and write it as TOML:

type MyConfig struct {
	Version int
	Name    string
	Tags    []string
}

Unmarshaling

Unmarshal reads a TOML document and fills a Go structure with its content.

Note that the struct variable names are capitalized, while the variables in the toml document are lowercase.

For example:

doc := `
version = 2
name = "go-toml"
tags = ["go", "toml"]
`

var cfg MyConfig
err := toml.Unmarshal([]byte(doc), &cfg)
if err != nil {
	panic(err)
}
fmt.Println("version:", cfg.Version)
fmt.Println("name:", cfg.Name)
fmt.Println("tags:", cfg.Tags)

// Output:
// version: 2
// name: go-toml
// tags: [go toml]

Here is an example using tables with some simple nesting:

doc := `
age = 45
fruits = ["apple", "pear"]

# these are very important!
[my-variables]
first = 1
second = 0.2
third = "abc"

# this is not so important.
[my-variables.b]
bfirst = 123
`

var Document struct {
	Age int
	Fruits []string

	Myvariables struct {
		First  int
		Second float64
		Third  string

		B struct {
			Bfirst int
		}
	} `toml:"my-variables"`
}

err := toml.Unmarshal([]byte(doc), &Document)
if err != nil {
	panic(err)
}

fmt.Println("age:", Document.Age)
fmt.Println("fruits:", Document.Fruits)
fmt.Println("my-variables.first:", Document.Myvariables.First)
fmt.Println("my-variables.second:", Document.Myvariables.Second)
fmt.Println("my-variables.third:", Document.Myvariables.Third)
fmt.Println("my-variables.B.Bfirst:", Document.Myvariables.B.Bfirst)

// Output:
// age: 45
// fruits: [apple pear]
// my-variables.first: 1
// my-variables.second: 0.2
// my-variables.third: abc
// my-variables.B.Bfirst: 123

Marshaling

Marshal is the opposite of Unmarshal: it represents a Go structure as a TOML document:

cfg := MyConfig{
	Version: 2,
	Name:    "go-toml",
	Tags:    []string{"go", "toml"},
}

b, err := toml.Marshal(cfg)
if err != nil {
	panic(err)
}
fmt.Println(string(b))

// Output:
// Version = 2
// Name = 'go-toml'
// Tags = ['go', 'toml']

Unstable API

This API does not yet follow the backward compatibility guarantees of this library. They provide early access to features that may have rough edges or an API subject to change.

Parser

Parser is the unstable API that allows iterative parsing of a TOML document at the AST level. See https://pkg.go.dev/github.com/pelletier/go-toml/v2/unstable.

Marshaler and Unmarshaler interfaces

unstable.Marshaler and unstable.Unmarshaler let types produce and consume their own raw TOML representation, similar to the equivalent encoding/json interfaces. They are opt-in: enable them with Encoder.EnableMarshalerInterface and Decoder.EnableUnmarshalerInterface.

RawMessage

unstable.RawMessage is a raw encoded TOML value implementing both interfaces above. Like json.RawMessage, it can delay the decoding of part of a document or splice pre-encoded TOML verbatim into the output.

Document editing

The unstable/edit package modifies TOML documents in place while preserving comments, whitespace, and ordering. Parse a document with edit.Parse, then Get, Set, and Delete values by key path — including array elements by index and keys inside inline tables — and read or write the comments attached to any key or table with Comment/SetComment. Only the bytes expressing an edit are rewritten, everything else is kept byte-for-byte. See https://pkg.go.dev/github.com/pelletier/go-toml/v2/unstable/edit.

Benchmarks

Execution time speedup compared to other Go TOML libraries:

Benchmarkgo-toml v1BurntSushi/toml
Marshal/HugoFrontMatter-22.3x2.4x
Marshal/ReferenceFile/map-22.2x2.6x
Marshal/ReferenceFile/struct-24.9x5.0x
Unmarshal/HugoFrontMatter-27.8x5.9x
Unmarshal/ReferenceFile/map-26.8x6.4x
Unmarshal/ReferenceFile/struct-26.8x6.3x
See more

The table above has the results of the most common use-cases. The table below contains the results of all benchmarks, including unrealistic ones. It is provided for completeness.

Benchmarkgo-toml v1BurntSushi/toml
Marshal/SimpleDocument/map-22.1x3.1x
Marshal/SimpleDocument/struct-23.4x4.8x
Unmarshal/SimpleDocument/map-210.1x7.0x
Unmarshal/SimpleDocument/struct-212.4x8.0x
UnmarshalDataset/example-28.2x6.9x
UnmarshalDataset/code-27.5x8.3x
UnmarshalDataset/twitter-29.0x7.6x
UnmarshalDataset/citm_catalog-25.0x4.5x
UnmarshalDataset/canada-26.4x4.7x
UnmarshalDataset/config-210.2x6.1x
geomean5.8x5.3x

This table can be generated with ./ci.sh benchmark -a -html.

Tools

Go-toml provides three handy command line tools:

  • tomljson: Reads a TOML file and outputs its JSON representation.

    $ go install github.com/pelletier/go-toml/v2/cmd/tomljson@latest
    $ tomljson --help
    
  • jsontoml: Reads a JSON file and outputs a TOML representation.

    $ go install github.com/pelletier/go-toml/v2/cmd/jsontoml@latest
    $ jsontoml --help
    
  • tomll: Lints and reformats a TOML file.

    $ go install github.com/pelletier/go-toml/v2/cmd/tomll@latest
    $ tomll --help
    

Docker image

Those tools are also available as a Docker image. For example, to use tomljson:

docker run -i ghcr.io/pelletier/go-toml:v2 tomljson < example.toml

Multiple versions are available on ghcr.io.

Versioning

Expect for parts explicitly marked otherwise, go-toml follows Semantic Versioning. The supported version of TOML is indicated at the beginning of this document. The last two major versions of Go are supported (see Go Release Policy).

License

The MIT License (MIT). Read LICENSE.