Output formats¶
RCL can print output in the formats below. The format can be selected with --format on the command line, and with format in build files. The format names are written lowercase.
json¶
Output pretty-printed JSON. Sets become lists, functions are not supported. Because RCL is a superset of JSON, every JSON value maps to itself. Note that YAML is a superset of JSON, so this format is appropriate for generating configuration for tools that accept YAML, such as Kubernetes and GitHub Actions.
Tip: You can quickly select JSON output on the command line with the
jeandjqshorthands.
{
series = "Nexus-6",
instances = {"Roy Batty", "Leon Kowalski"},
}
Formats as:
{
"instances": ["Leon Kowalski", "Roy Batty"],
"series": "Nexus-6"
}
json-lines¶
If the document is a list, output every element as a JSON value on its own line, consistent with the JSON lines format. Top-level values other than lists are not valid for this format.
[
{ name = "Roy Batty", serial = "N6MAA10816" },
{ name = "Leon Kowalski", serial = "N6MAC41717" },
]
Formats as:
{"name": "Roy Batty", "serial": "N6MAA10816"}
{"name": "Leon Kowalski", "serial": "N6MAC41717"}
raw¶
If the document is a string, output the string itself. If the document is a list or set of strings, output each string on its own line.
Tip: You can quickly select raw output on the command line with the
reandrqshorthands.
["First line", "Second line\nThird line"]
Formats as:
First line
Second line
Third line
rcl¶
Output pretty-printed RCL.
{
"where_possible": "Record syntax will be used.",
"where impossible": "Expression form is used.",
}
Formats as:
{
"where impossible": "Expression form is used.",
where_possible = "Record syntax will be used.",
}
systemd¶
Output as a systemd unit. The format is superficially similar to TOML, but handles nested data differently. The top-level value must always be a dict. Its keys become sections. Its values must be dicts as well, which become the section contents:
{
Unit = {
Description = "Example systemd unit.",
After = "network-online.target",
},
}
[Unit]
After=network-online.target
Description="Example systemd unit."
Systemd allows repeating keys. To emit those, use a list or set value in RCL:
{
Service = {
BindReadOnlyPaths = ["/etc/resolv.conf", "/var/www"],
},
}
[Service]
BindReadOnlyPaths=/etc/resolv.conf
BindReadOnlyPaths=/var/www
Some settings allow space-separated values. To emit those, use a nested list or set:
{
Service = {
ExecStart = [["/usr/bin/nsd", "-P", "", "-c", "/etc/nsd.conf"]],
},
},
[Service]
ExecStart=/usr/bin/nsd -P "" -c /etc/nsd/nsd.conf
For some settings, systemd accepts the empty string to clear previous assignments. While Value="" and Value= mean the same thing to systemd, the latter is more common, and therefore might communicate the intent more clearly. To emit an empty value from RCL, use null:
{
Service = {
Environment = [
null,
["LOG_LEVEL=debug", "PORT=8000"],
"ENVIRONMENT=prod",
],
},
}
[Service]
Environment=
Environment=LOG_LEVEL=debug PORT=8000
Environment=ENVIRONMENT=prod
Finally, some units support repeated sections. To emit those, wrap the sections in a list or set:
{
Route = [
{ Gateway = "0.0.0.0", Table = 1 },
{ Gateway = "::", Table = 2 },
],
}
[Route]
Gateway=0.0.0.0
Table=1
[Route]
Gateway=::
Table=2
RCL will use escape sequences and quote strings when needed to keep the unit file valid, and to preserve values exactly. For some settings, such as ExecStart=, systemd performs environment variable substitution and specifier substitution, which means that $ and % have special meaning for those settings. RCL does not apply any special handling for these characters.
toml¶
Alias for toml-1.0.
toml-1.0¶
Output as TOML 1.0. This version is the most widely supported, but can be less readable because inline tables cannot span multiple lines.
{
profile = {
release = {
lto = "thin",
panic = "abort",
strip = "true",
},
},
}
Formats as:
[profile]
release = { lto = "thin", panic = "abort", strip = "true" }
toml-1.1¶
Output TOML 1.1. This version supports multi-line tables, but it was only released in December 2025, so it is less widely supported. The same example as before outputs as follows for a 50-column target line width:
[profile]
release = {
lto = "thin",
panic = "abort",
strip = "true",
}
yaml-stream¶
If the document is a list, output every element as a JSON document (which is also a valid YAML document), prefixed by the --- YAML document separator. Top-level values other than lists are not valid for this format.
[
{ name = "Roy Batty", serial = "N6MAA10816" },
{ name = "Leon Kowalski", serial = "N6MAC41717" },
]
Formats as:
---
{
"name": "Roy Batty",
"serial": "N6MAA10816"
}
---
{
"name": "Leon Kowalski",
"serial": "N6MAC41717"
}