TOML Cheatsheet

Strings

Use this TOML reference while you build software engineering projects, review code, or refresh the syntax you reach for most.

Four string forms

Two axes: basic vs literal (escapes on or off) and single-line vs multi-line.

FormDelimiterEscapesNewlines
basic"..."yesno
literal'...'noneno
multi-line basic"""..."""yesyes
multi-line literal'''...'''noneyes
basic = "I'm a string. \"You can quote me.\" Name\tJos\u00E9\nLoc\tSF."
literal = 'C:\Users\nodejs\templates'
ml_basic = """
Roses are red
Violets are blue"""
ml_literal = '''
The first newline is trimmed.
   All other whitespace is preserved.
'''

The escape table (basic strings only)

EscapeMeaning
\bbackspace, U+0008
\ttab, U+0009
\nline feed, U+000A
\fform feed, U+000C
\rcarriage return, U+000D
\"quote, U+0022
\\backslash, U+005C
\uXXXX4-digit Unicode scalar
\UXXXXXXXX8-digit Unicode scalar

That is the whole list in TOML 1.0.0. There is no \', no \/, no \0, no \xNN, and no octal. Any other backslash is a hard error, not a passthrough: "a\qb" fails with Unescaped '\' in a string. A literal newline inside a single-line basic string is also an error.

TOML 1.1 adds \e and \xNN, but 1.1 is unreleased. Do not use them.

Literal strings: no escapes at all

Inside '...' every character is itself, including backslashes. There is no way to include a single quote in a single-line literal string, since '' does not escape it.

winpath = 'C:\Users\nick\new\tmp'
regex = '\d{4}-\d{2}-\d{2}'
quoted = 'Tom "Dubs" Preston-Werner'

parses to:

{"winpath": "C:\\Users\\nick\\new\\tmp",
 "regex": "\\d{4}-\\d{2}-\\d{2}",
 "quoted": "Tom \"Dubs\" Preston-Werner"}

Those \\ are JSON's escaping of a single literal backslash. Literal strings are the correct default for Windows paths, regexes, and glob patterns. The same \d{4} inside a basic string would fail to parse.

Multi-line basic strings

""" may span lines and takes every escape a basic string does.

- A newline immediately after the opening """ is trimmed. Nothing else is. - One or two consecutive " need no escaping inside the block. Three do. - A backslash at end of line trims the newline and all leading whitespace on the next line, which is how you wrap a long single-line value.

str1 = "The quick brown fox jumps over the lazy dog."

str2 = """
The quick brown \


  fox jumps over \
    the lazy dog."""

str1 == str2 is True, verified with tomllib. Both are the plain sentence with no newlines. The blank lines vanish too, because the trim eats every whitespace character including newlines until the next non-whitespace.

two_quotes = """he said ""hi"" and left"""
three = """three: \"\"\" done"""

parse to 'he said ""hi"" and left' and 'three: """ done'.

Multi-line literal strings

''' spans lines with zero escape processing. The leading-newline trim still applies. Up to two consecutive ' are fine inside.

regex2 = '''I [dw]on't need \d{2} apples'''

lines = '''
The first newline is
trimmed in raw strings.
   All other whitespace
   is preserved.
'''

lines is "The first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n". Note the trailing \n, since only the leading newline is trimmed. There is no chomping control and no dedenting, so indentation you write is indentation you get.

Picking a form

You needUse
plain text"basic"
a Windows path'C:\tmp\new'
a regex'\d+'
a glob'**/*.py'
a tab or \n inside"a\tb\nc"
a long value wrapped in the source"""..\ ..."""
an embedded script or SQL'''...'''
an embedded template with ${} or {{}}'''...'''
a single quote inside a one-line string"it's"
a double quote inside a one-line string'say "hi"' or "say \"hi\""
[scripts]
migrate = '''
psql "$DATABASE_URL" <<'SQL'
  ALTER TABLE users ADD COLUMN tz text DEFAULT 'UTC';
SQL
'''

Multi-line literal is the one to reach for whenever the payload is code, because nothing in it needs escaping.