Make
configuration
boring again

RCL is a domain-specific language for specifying human-written data with just enough abstraction to avoid repetition. It extends json into a simple functional programming language that resembles Python and Nix.

{
  // A silly snippet to show some
  // features in a limited space.
  let data: List[String] = 
    import "data.rcl";
  assert
    data.contains("Assertions"),
    "Assertions are supported";
  let f = () => [
    "List", 
    "Dict", 
    "Set",
  ];
  features = [
    for d in data: d,
    for collection in f():
    f"{collection} comprehensions",
  ],
  export-to = "json, yaml, toml, ...",
}

Note! RCL is a hobby project without stability promise. It is usable, but also experimental and incomplete.

Connect anything

Generate json, yaml, toml, or other text-based configuration for tools that do not natively talk to each other, all from a single source of truth.

Remove repetition

Stop copy-pasting. Use variables, list comprehensions, and functions to avoid duplication. Bump ubuntu-20.04 to 24.04 in one place.

Fight complexity, not tools

Spend time building your infrastructure, not debugging whitespace and escaping issues in your string templates. Generate correct yaml, json, and toml.

Familiar syntax

Have you used Python, TypeScript or Rust before? Then you will find RCL obvious to read and natural to write.

Built-in json queries

Need to drill down into a json document, but can’t figure out the jq syntax? Try rcl query instead. Scroll down for an example.

Python module

You can always export json from the command line and load it into your program. For Python we can skip that intermediate stage: rcl.loads is a drop-in replacement for json.loads.

Try it yourself

Suppose we run a webserver that serves both www.example.com and docs.example.com. We have to create two very similar DNS records pointing to that server’s address. One way to manage those is with Terraform/OpenTofu. The output below is a simplified form of a json config that defines the records.

rcl evaluate --format=json

input

{
  let tld = "com";
  // for tld in ["com", "net"]:
  for subdomain in ["docs", "www"]:
  f"a_record_{subdomain}_example_{tld}":
  {
    domain = "example.com",
    name = subdomain,
    type = "A",
    value = "93.184.216.34",
  }
}
{
  let tld = "com";
  // for tld in ["com", "net"]:
  for subdomain in ["docs", "www"]:
  f"a_record_{subdomain}_example_{tld}":
  {
    domain = "example.com",
    name = subdomain,
    type = "A",
    value = "93.184.216.34",
  }
}

output

{
  "a_record_docs_example_com": {
    "domain": "example.com",
    "name": "docs",
    "type": "A",
    "value": "93.184.216.34"
  },
  "a_record_www_example_com": {
    "domain": "example.com",
    "name": "www",
    "type": "A",
    "value": "93.184.216.34"
  }
}

The input above is editable. How would you change it to emit records for www.example.net and docs.example.net in addition to example.com? Try uncommenting the tld loop.

Intuitive json queries

Suppose a cloud provider has an API that returns the regions it supports, and you want to know the details of the region with id nrt. Below is a query that does this.

$ curl --silent 
https://api.vultr.com/v2/regions
| rcl query
input.regions.key_by(r => r.id).nrt
{ city = "Tokyo", continent = "Asia", country = "JP", id = "nrt", options = [ "ddos_protection", "block_storage_high_perf", "block_storage_storage_opt", "load_balancers", "kubernetes", ], }

The above query is editable. Can you change the query to return the ids of all regions where the block_storage_high_perf option is available? Some ideas to get you started:

Installation

RCL is written in Rust and has few dependencies, so it is quick and easy to build from source with Cargo. There is no need to pipe arbitrary code from the web into your shell.

$ git clone https://github.com/ruuda/rcl
$ cargo build --release
$ target/release/rcl --help

Further resources

Free & open source

RCL is free/libre software, licensed under the Apache 2.0 license. The project is developed in the open and the source code is available on GitHub and Codeberg.

Support RCL

One thing that holds RCL back from being useful to more people is the lack of widespread support for syntax highlighting, in particular on platforms such as GitHub. If RCL is useful to you, you can help by using RCL publicly in a GitHub repository to demonstrate traction. Use it seriously of course, please don’t game the metric. Other things you can help with are getting RCL packaged for your favorite package manager, and developing syntax highlighting for your favorite editor if it is not yet supported.

Get in touch

If you want to share your thoughts, you can send an email or reach out on Mastodon. To report a technical defect you can open an issue on Codeberg or on GitHub.