TOML (Tom's Obvious, Minimal Language)
repository·main·Indexed 12 days ago
https://github.com/toml-lang/tomlA minimal, human-readable configuration file format designed to map unambiguously to hash tables. TOML supports data types including strings, integers, floats, booleans, dates/times, arrays, and tables, providing a standardized alternative to JSON, YAML, and INI for configuration purposes.
What's inside TOML
- TOML (Tom's Obvious, Minimal Language) is a minimal configuration file format designed to be easy to read due to obvious semantics. Its primary goal is to map unambiguously to a hash table and be easily parsed into data structures across a wide variety of programming languages.
Format integers in TOML
mainIntegers are whole numbers. They can be positive (prefixed with
+) or negative (prefixed with-).Readability
You can use underscores (
_) between digits to enhance readability, provided each underscore is surrounded by at least one digit.Bases
- Hexadecimal: Prefix with
0x(case-insensitive). - Octal: Prefix with
0o. - Binary: Prefix with
0b.
Constraints
- Leading zeros are not allowed in decimal integers.
- In non-decimal formats (hex, octal, binary), leading zeros are allowed after the prefix.
- Implementations should ideally support at least 64-bit signed integers.
int1 = +99 int2 = 42 int3 = 0 int4 = -17 # Using underscores int5 = 1_000 int6 = 5_349_221 # Hexadecimal, Octal, and Binary hex1 = 0xDEADBEEF oct1 = 0o01234567 bin1 = 0b11010110- Hexadecimal: Prefix with
Use Arrays in TOML
mainArrays are ordered values surrounded by square brackets
[]. They can contain values of the same type or mixed types. Whitespace is ignored, and elements are separated by commas. Arrays can span multiple lines and support trailing commas. Indentation is treated as whitespace and ignored.integers = [ 1, 2, 3 ] colors = [ "red", "yellow", "green" ] nested_arrays_of_ints = [ [ 1, 2 ], [3, 4, 5] ] nested_mixed_array = [ [ 1, 2 ], ["a", "b", "c"] ] string_array = [ "all", 'strings', """are the same""", '''type''' ] # Mixed-type arrays are allowed numbers = [ 0.1, 0.2, 0.5, 1, 2, 5 ] contributors = [ "Foo Bar <foo@example.com>", { name = "Baz Qux", email = "bazqux@example.com", url = "https://example.com/bazqux" } ] # Multi-line arrays with trailing commas integers2 = [ 1, 2, 3 ] integers3 = [ 1, 2, # this is ok ]Represent dates and times in TOML
mainTOML provides several ways to represent temporal data, primarily based on RFC 3339.
Offset Date-Time
Represents a specific instant in time with an offset. Format:
YYYY-MM-DDTHH:MM:SSZorYYYY-MM-DDTHH:MM:SS-HH:MM.Local Date-Time
Represents a date and time without any relation to an offset or timezone.
Local Date
Represents an entire day without any relation to an offset or timezone.
Local Time
Represents a time of day without any relation to a specific day or offset.
Common Rules
- Precision: Implementations must support at least millisecond precision. Extra digits should be truncated, not rounded.
- Omitted Seconds: If seconds are omitted,
:00is assumed. - Delimiters: The
Tdelimiter between date and time can be replaced by a space for readability.
# Offset Date-Time o dt1 = 1979-05-27T07:32:00Z o dt2 = 1979-05-27 07:32:00-07:00 # Local Date-Time ldt1 = 1979-05-27T07:32:00 # Local Date ld1 = 1979-05-27 # Local Time lt1 = 07:32:00Use Inline Tables for compact data
mainInline tables provide a compact syntax for expressing tables using curly braces
{}. They are useful for grouping nested data.Constraints:
- Inline tables are fully self-contained. You cannot add keys or sub-tables to an inline table from outside its braces.
- You cannot use an inline table to add keys to an already-defined standard table.
name = { first = "Tom", last = "Preston-Werner" } point = {x=1, y=2} # Nested inline tables contact = { personal = { name = "Donald Duck", email = "donald@duckburg.com", }, work = { name = "Coin cleaner", email = "donald@ScroogeCorp.com", }, }Use Arrays of Tables
mainArrays of tables are defined using double brackets
[[header]]. The first instance defines the array and its first element; subsequent instances create new elements in the array. This is the TOML equivalent of a JSON array of objects.Rules:
- Any reference to an array of tables points to the most recently defined element.
- You can define sub-tables or sub-arrays of tables inside the most recent element.
- Error Conditions:
- You cannot define a sub-table for a parent that hasn't been defined yet.
- You cannot append to a statically defined array (e.g.,
fruits = []followed by[[fruits]]is invalid). - You cannot redefine a table as an array or vice versa.
[[product]] name = "Hammer" sku = 738594937 [[product]] # empty table within the array [[product]] name = "Nail" sku = 284758393 color = "gray" # Nested array of tables within an array of tables [[fruits]] name = "apple" [fruits.physical] color = "red" shape = "round" [[fruits.varieties]] name = "red delicious" [[fruits.varieties]] name = "granny smith"Express strings in TOML
mainTOML supports four types of strings. All strings must contain only Unicode characters. For binary data, use external encoding like Base64 instead of escape codes.
1. Basic Strings
Surrounded by double quotes (
"). They allow escape sequences for special characters.2. Multi-line Basic Strings
Surrounded by triple double quotes (
"""). They allow newlines. A newline immediately following the opening delimiter is trimmed. You can use a "line ending backslash" (\) to break long strings across lines without introducing extra whitespace.3. Literal Strings
Surrounded by single quotes (
'). They do not allow any escaping; what you see is what you get. This is ideal for Windows paths or regular expressions. They must be on a single line.4. Multi-line Literal Strings
Surrounded by triple single quotes (
'''). They allow newlines and do not allow escaping. A newline immediately following the opening delimiter is trimmed. You can use up to two single quotes inside these strings, but sequences of three or more are not permitted.# Basic string str = "I'm a string. \"You can quote me\"." # Multi-line basic string str1 = """ Roses are red Violets are blue""" # Multi-line basic string with line-ending backslash str2 = """ The quick brown \ \n fox jumps over \\n the lazy dog.""" # Literal string (no escaping) winpath = 'C:\Users\nodejs\templates' # Multi-line literal string lines = ''' The first newline is trimmed in literal strings. '''Manage Nested Tables with Dotted Keys
mainDotted keys allow you to build nested structures. When you use a dotted key, you are effectively defining a table.
Rules for nesting:
- You can add to a table as long as the key hasn't been directly defined as a non-table value.
- Invalid Pattern: You cannot turn an existing value (like an integer) into a table. If
fruit.apple = 1is defined, you cannot later definefruit.apple.smooth = true. - Best Practice: Define dotted keys in an organized manner. It is recommended to define all properties for a specific branch before moving to the next to avoid confusion.
Warning on Numeric Dotted Keys: If you use a dotted key that looks like a float (e.g.,
3.14159), it will be interpreted as a 2-part dotted key (a nested structure) rather than a float value.# Valid: Creating a table via dotted keys fruit.apple.smooth = true fruit.orange = 2 # INVALID: Trying to turn an integer into a table fruit.apple = 1 fruit.apple.smooth = true # WARNING: This is a nested structure, NOT a float 3.14159 = "pi" # Maps to: { "3": { "14159": "pi" } }Use Bare, Quoted, and Dotted Keys
mainTOML supports three types of keys:
- Bare keys: Contain only ASCII letters, digits, underscores, and dashes (
A-Za-z0-9_-). They are interpreted as strings even if they consist only of digits. - Quoted keys: Follow the rules of basic or literal strings. Use these when you need special characters or spaces. Best practice is to use bare keys whenever possible.
- Dotted keys: A sequence of bare or quoted keys joined by dots. This creates a nested structure (tables) similar to JSON objects.
Important Notes:
- An empty quoted key (
"" = "blank") is valid but discouraged. - You cannot use multi-line strings to define quoted keys.
- Defining a key multiple times is invalid.
- Dotted keys can be used to define tables implicitly.
# Bare keys key = "value" bare_key = "value" bare-key = "value" 1234 = "value" # Quoted keys "127.0.0.1" = "value" "character encoding" = "value" 'key2' = "value" # Dotted keys (creates nested structure) name = "Orange" physical.color = "orange" physical.shape = "round" site."google.com" = true- Bare keys: Contain only ASCII letters, digits, underscores, and dashes (
Compare TOML with JSON, YAML, and INI
mainUnderstanding how TOML relates to other formats can help determine if it is the right choice for your use case:
- vs. JSON: Like JSON, TOML is simple and uses ubiquitous data types, making it easy to parse. However, unlike JSON, TOML allows comments.
- vs. YAML: Like YAML, TOML emphasizes human readability and supports comments. However, TOML maintains a higher level of simplicity compared to YAML.
- vs. INI: While similar in syntax and use case, TOML is a standardized format that handles deep nesting gracefully, whereas INI lacks a standard and struggles with more than one or two levels of nesting.
Important Limitations: TOML is intended for configuration, not for serializing arbitrary data structures. It always requires a hash table at the top level and does not permit top-level arrays or floats. Additionally, there is no standard identifier for the start or end of a file, so streaming TOML requires application-layer negotiation.
Understand TOML Preliminaries
mainBefore writing TOML, be aware of these fundamental rules:
- Case-sensitivity: TOML is case-sensitive.
- Whitespace: Whitespace consists of tabs (U+0009) and spaces (U+0020).
- Newlines: Newlines are LF (U+000A) or CRLF (U+000D U+000A).
- Encoding: A TOML file must be a valid UTF-8 encoded Unicode document.
Format floats in TOML
mainA float consists of an integer part followed by a fractional part and/or an exponent part.
Syntax
- Fractional part: A decimal point followed by one or more digits.
- Exponent part: An
Eorefollowed by an integer part. - Underscores: Allowed between digits for readability.
Special Values
Special float values must be lowercase:
infor+inf: positive infinity-inf: negative infinitynan: not a number+nan: same asnan-nan: negative NaN
Invalid Floats
Decimal points must be surrounded by digits. The following are invalid:
.7(missing leading digit)7.(missing trailing digit)3.e+20(missing fractional digits before exponent)
Implementations should ideally support at least IEEE 754 binary64 values.
flt1 = +1.0 flt2 = 3.1415 flt4 = 5e+22 flt7 = 6.626e-34 # Underscores flt8 = 224_617.445_991_228 # Special values sf1 = inf sf4 = nan