Skip to content
TOML parser for Golang with reflection.
Go Other
  1. Go 99.8%
  2. Other 0.2%
Branch: master
Clone or download

Latest commit

BurntSushi Merge pull request #230 from gregwebs/cmd-license-wtf
switch the licenses of cmd/ to be the same as the root
Latest commit 3012a1d Aug 15, 2018


Type Name Latest commit message Commit time
Failed to load latest commit information.
_examples Various formatting fixes. 80 cols. Jan 25, 2015
cmd switch the licenses of the cmd to be the same as the root Aug 14, 2018
.gitignore Ignore test binary. May 14, 2014
.travis.yml Run .travis.yml against latest Go versions Jul 16, 2016
COMPATIBLE update compatible version note Mar 15, 2017
COPYING update copyright Jun 23, 2017
Makefile Recompile when testing. May 21, 2014 Fix some outdated links and version numbers Mar 18, 2017
decode.go Fix incorrect error message Jul 7, 2016
decode_meta.go simplify return paths by removing 'else' block (golint) Jul 12, 2016
decode_test.go Complete the testing for decoding datetime with UTC offset Jun 26, 2017
doc.go update compatible version note Mar 15, 2017
encode.go Spell it "newline" rather than "new line" Mar 7, 2017
encode_test.go Remove usage of log in tests Apr 26, 2016
encoding_types.go Various formatting fixes. 80 cols. Jan 25, 2015
encoding_types_1.1.go Various formatting fixes. 80 cols. Jan 25, 2015
lex.go Allow '+' in Datetime lexing Jun 22, 2017
parse.go Merge remote-tracking branch 'ttacon/master' Mar 5, 2017
session.vim initial commit. i think the lexer is good. Feb 25, 2013
type_check.go Various formatting fixes. 80 cols. Jan 25, 2015
type_fields.go Encoder: treat tagged anonymous structs as non-anonymous Mar 16, 2016

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 v0.4.0



go get

Try the toml validator:

go get
tomlv some-toml-file.toml

Build Status GoDoc


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"`

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

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}.

You can’t perform that action at this time.