TOML parser for Golang with reflection.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Martin Tournoij e0af6a2568 math.MaxInt was added in Go 1.17, so don't use it. 3 weeks ago
.github/workflows Test Go 1.17 2 months ago
_examples Various formatting fixes. 80 cols. 7 years ago
cmd Improve error output in some failing tests 2 months ago
internal Fix tests on 32bit platforms 2 months ago
.gitignore Fix tests in GitHub actions 4 months ago
COMPATIBLE Implement dotted keys 4 months ago
COPYING update copyright 4 years ago Add mention of changelog in README 2 months ago
decode.go Remove unused `unifyDatetime` (#315) 1 month ago
decode_go116.go Update documentation 2 months ago
decode_go116_test.go Add Decoder struct and DecodeFS() 4 months ago
decode_meta.go Update documentation 2 months ago
decode_test.go Move toml.LocalDatetime to internal package 2 months ago
deprecated.go Add Decoder struct and DecodeFS() 4 months ago
doc.go Update documentation 2 months ago
encode.go math.MaxInt was added in Go 1.17, so don't use it. 3 weeks ago
encode_test.go Fix nested structs on 32bit archs 3 weeks ago
example_test.go Move the tested examples to example_test.go 4 months ago
fuzz_test.go Update documentation 2 months ago
go.mod Put the in internal/ (#313) 2 months ago
go.sum Put the in internal/ (#313) 2 months ago
lex.go Multiline strings ending in 6 or more quotes should fail 4 months ago
move_test.go Deal with local datetimes, dates, and times better 3 months ago
parse.go Move toml.LocalDatetime to internal package 2 months ago
toml_test.go Improve error output in some failing tests 2 months ago
type_check.go Allow mixed values in arrays 3 months ago
type_fields.go Encoder: treat tagged anonymous structs as non-anonymous 6 years ago

TOML parser and encoder for Go with reflection

TOML stands for Tom's Obvious, Minimal Language. This Go package provides a reflection interface similar to Go's standard library json and xml packages. This package also supports the encoding.TextUnmarshaler and encoding.TextMarshaler interfaces so that you can define custom data representations. (There is an example of this below.)

Compatible with TOML version v1.0.0.


See the releases page for a changelog; this information is also in the git tag annotations (e.g. git show v0.4.0).

This library requires Go 1.13 or newer; install it with:

$ go get

It also comes with a TOML validator CLI tool:

$ go get
$ tomlv some-toml-file.toml


This package passes all tests in toml-test for both the decoder and the encoder.


This package works similarly to how the Go standard library handles XML and JSON. Namely, data is loaded into Go values via reflection.

For the simplest example, consider some TOML file as just a list of keys and values:

Age = 25
Cats = [ "Cauchy", "Plato" ]
Pi = 3.14
Perfection = [ 6, 28, 496, 8128 ]
DOB = 1987-07-05T05:45:00Z

Which could be defined in Go as:

type Config struct {
	Age        int
	Cats       []string
	Pi         float64
	Perfection []int
	DOB        time.Time // requires `import time`

And then decoded with:

var conf Config
if _, err := toml.Decode(tomlData, &conf); err != nil {
  // handle error

You can also use struct tags if your struct field name doesn't map to a TOML key value directly:

some_key_NAME = "wat"
type TOML struct {
  ObscureKey string `toml:"some_key_NAME"`

Beware that like other most other decoders only exported fields are considered when encoding and decoding; private fields are silently ignored.

Using the encoding.TextUnmarshaler interface

Here's an example that automatically parses duration strings into time.Duration values:

name = "Thunder Road"
duration = "4m49s"

name = "Stairway to Heaven"
duration = "8m03s"

Which can be decoded with:

type song struct {
	Name     string
	Duration duration
type songs struct {
	Song []song
var favorites songs
if _, err := toml.Decode(blob, &favorites); err != nil {

for _, s := range favorites.Song {
	fmt.Printf("%s (%s)\n", s.Name, s.Duration)

And you'll also need a duration type that satisfies the encoding.TextUnmarshaler interface:

type duration struct {

func (d *duration) UnmarshalText(text []byte) error {
	var err error
	d.Duration, err = time.ParseDuration(string(text))
	return err

To target TOML specifically you can implement UnmarshalTOML TOML interface in a similar way.

More complex usage

Here's an example of how to load the example from the official spec page:

# This is a TOML document. Boom.

title = "TOML Example"

name = "Tom Preston-Werner"
organization = "GitHub"
bio = "GitHub Cofounder & CEO\nLikes tater tots and beer."
dob = 1979-05-27T07:32:00Z # First class dates? Why not?

server = ""
ports = [ 8001, 8001, 8002 ]
connection_max = 5000
enabled = true


  # You can indent as you please. Tabs or spaces. TOML don't care.
  ip = ""
  dc = "eqdc10"

  ip = ""
  dc = "eqdc10"

data = [ ["gamma", "delta"], [1, 2] ] # just an update to make sure parsers support it

# Line breaks are OK when inside arrays
hosts = [

And the corresponding Go types are:

type tomlConfig struct {
	Title   string
	Owner   ownerInfo
	DB      database `toml:"database"`
	Servers map[string]server
	Clients clients

type ownerInfo struct {
	Name string
	Org  string `toml:"organization"`
	Bio  string
	DOB  time.Time

type database struct {
	Server  string
	Ports   []int
	ConnMax int `toml:"connection_max"`
	Enabled bool

type server struct {
	IP string
	DC string

type clients struct {
	Data  [][]interface{}
	Hosts []string

Note that a case insensitive match will be tried if an exact match can't be found.

A working example of the above can be found in _examples/example.{go,toml}.