Introduction



What is Cue?

Cue is a purpose built logical language for working with config, schemas, data, and executing on these things. Most people start with Cue by validating and generating configuration. They then move on to data templating, runtime input validation, code generation, scripting, pipelines, and oh so much more which we’ll cover throughout these tutorials.

First, you should understand that Cue is not a general purpose language and instead aims for Turing-incompleteness. The underlying philosophy is that it is harder for both humans and tooling to understand configuration and data that has been programmed together. The saying is “Wrap code in data, not data in code.”

Cue is a superset of JSON. This means you can represent any JSON in Cue with a slightly different syntax and then some Cue super powers to boot!

music.json

{
  "albums": [
    {
      "artist": "Led Zeppelin",
      "album": "BBC Sessions",
      "date": "1997-11-11"
    }
  ]
}

music.cue

albums: [{
	artist: "Led Zeppelin"
	album:  "BBC Sessions"
	date:   "1997-11-11"
}]

If you think about JSONSchema vs JSON, they are separate concepts. One defines a schema, the other is data. In Cue they are the same. Cue merges types and values into a single concept, the value lattice. This gives us the ability to define schemas, refine with constraints, and create valid data in the same file. It also means defining schemas is more natural with how we think about and write code as humans.

In Cue, types, values, and constraints are all the same. There is no difference (to Cue) between the schema, the data, or the rules. Cue has a value hierarchy which connects top (_), the any value, to bottom (_|_), the void value. Technically it is a lattice or partially ordered set of values where every pair of values has a unique upper bound and a greatest lower bound. The entire lattice starts from a singular root (top, _, any), ends with a single leaf (bottom, _|_, void), and all other values are between these two, partially ordered.

package hierarchy

import "list"

#Schema: {
	hello: string
	life:  int
	pi:    float
	nums: [...int]
	struct: {...}
}

#Constrained: #Schema & {
	hello: =~"[a-z]+"
	life:  >0
	nums:  list.MaxItems(10)
}

Value: #Constrained & {
	hello: "world"
	life:  42
	pi:    3.14
	nums: [1, 2, 3, 4, 5]
	struct: {
		a: "a"
		b: "b"
	}
}

In the code above, we have a “type” #Schema, some constraints #Constrained, and a Value. #Definitions: had slightly different semantics and rules than Values: which we will expand on in the tutorial. Cue has packages, imports, all the typical basic types, lists, and structs. The & combines two or more Cue “values” (all three of {type, constraint, value}) in a conjunction (“and”) and ensures that the result is valid and correct. There is also a disjunction (“or”) operator |. In #Constrained, you can see a regexp and logical operators as well as a builtin from the standard library. We’ll go into the in greater depth later.

CUE stands for Configure, Unify, Execute

With Cue, when you write code, it is not instructions for the computer. Rather, you are specifying something and Cue tells you if it is valid or not. If this sounds weird right now, worry not, it becomes natural pretty quickly. Under the hood, Cue analyzes your code with graph unification algorithms based in part on NLP techniques from the 90’s (pre deep learning). Because of this, you can spread configuration across directories and packages, pulling common schema, constraint, logic, and values into reusable modules.

What is CUE?

It’s the new logical tool in your programming toolbox. Cue will help you manage configuration, validate data, share schemas, generate code, and much more. Cue is still quite young and has a bright future. I personally see it sweeping through the devops world first. My hope is that you join us and bring your own use cases and ideas to the community.

What you need to dive in

You’ll need a text editor and the cue cli. If you haven’t already, go ahead and download the latest version from the GitHub releases. Beyond that, most examples will be run from the command line, so a dedicated terminal is often helpful, but VS Code is just fine too. If anything extra is needed for a particular section, the instructions for it will be found there.

Where to get help?

Several options are available

  1. cue help, the builtin help command
  2. GitHub Discussions (trying to move here for longevity)
  3. Cuelang Slack (and the invite if needed)
  4. Hofstadter offers commercial support and services for Cue
We'll never share your email with anyone else.
2023 Hofstadter, Inc