diff --git a/encoding/openapi/build.go b/encoding/openapi/build.go
new file mode 100644
index 0000000..0cef528
--- /dev/null
+++ b/encoding/openapi/build.go
@@ -0,0 +1,696 @@
+// Copyright 2019 CUE Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package openapi
+
+import (
+	"fmt"
+	"math"
+	"path"
+	"strings"
+
+	"cuelang.org/go/cue"
+)
+
+type buildContext struct {
+	refPrefix string
+	path      []string
+
+	expandRefs bool
+
+	schemas *orderedMap
+}
+
+type oaSchema = orderedMap
+
+type typeFunc func(b *builder, a cue.Value)
+
+func components(inst *cue.Instance, cfg *Config) (comps *orderedMap, err error) {
+	c := buildContext{
+		refPrefix:  "components/schema",
+		expandRefs: cfg.ExpandReferences,
+		schemas:    &orderedMap{},
+	}
+
+	defer func() {
+		if x := recover(); x != nil {
+			// TODO: check if it's one of our own.
+			path := strings.Join(c.path, ".")
+			err = fmt.Errorf("error: %s: %v", path, x)
+		}
+	}()
+
+	schemas := &orderedMap{}
+	schemas.Set("schema", c.schemas)
+	comps = &orderedMap{}
+	comps.Set("openapi", "3.0.0")
+	comps.Set("components", schemas)
+
+	i, err := inst.Value().Fields()
+	if err != nil {
+		return nil, err
+	}
+	for i.Next() {
+		// message, enum, or constant.
+		c.schemas.Set(i.Label(), c.build(i.Value()))
+	}
+	return comps, nil
+}
+
+func (c *buildContext) build(v cue.Value) *oaSchema {
+	return newRootBuilder(c).schema(v)
+}
+
+func (b *builder) schema(v cue.Value) *oaSchema {
+	c := newRootBuilder(b.ctx)
+	c.value(v, nil)
+	schema := c.finish()
+	doc := []string{}
+	for _, d := range v.Doc() {
+		doc = append(doc, d.Text())
+	}
+	if len(doc) > 0 {
+		str := strings.TrimSpace(strings.Join(doc, "\n"))
+		schema.Prepend("description", str)
+	}
+	return schema
+}
+
+func (b *builder) value(v cue.Value, f typeFunc) {
+	count := 0
+	var values cue.Value
+	if b.ctx.expandRefs {
+		values = v
+		count = 1
+	} else {
+		for _, v := range appendSplit(nil, cue.AndOp, v) {
+			// This may be a reference to an enum. So we need to check references before
+			// dissecting them.
+			switch r := v.Reference(); {
+			case r != nil:
+				b.addRef(r)
+			default:
+				count++
+				values = values.Unify(v)
+			}
+		}
+	}
+
+	if count > 0 { // TODO: implement IsAny.
+		// NOTE: Eval is not necessary here. Removing it will yield
+		// different results that also are correct. The difference is that
+		// Eval detects and eliminates impossible combinations at the
+		// expense of having potentially much larger configurations due to
+		// a combinatorial explosion. This rudimentary check picks the least
+		// fo the two extreme forms.
+		if eval := values.Eval(); countNodes(eval) < countNodes(values) {
+			values = eval
+		}
+
+		for _, v := range appendSplit(nil, cue.AndOp, values) {
+			switch {
+			case isConcrete(v):
+				b.dispatch(f, v)
+				b.set("enum", []interface{}{decode(v)})
+
+			default:
+				if a := appendSplit(nil, cue.OrOp, v); len(a) > 1 {
+					b.disjunction(a, f)
+				} else {
+					v = a[0]
+					if err := v.Err(); err != nil {
+						panic(err)
+					}
+					b.dispatch(f, v)
+				}
+			}
+		}
+	}
+
+	if v, ok := v.Default(); ok && v.IsConcrete() {
+		v.Default()
+		b.set("default", v)
+	}
+}
+
+func appendSplit(a []cue.Value, splitBy cue.Op, v cue.Value) []cue.Value {
+	op, args := v.Expr()
+	if op == cue.NoOp && len(args) > 0 {
+		// TODO: this is to deal with default value removal. This may change
+		// whe we completely separate default values from values.
+		a = append(a, args...)
+	} else if op != splitBy {
+		a = append(a, v)
+	} else {
+		for _, v := range args {
+			a = appendSplit(a, splitBy, v)
+		}
+	}
+	return a
+}
+
+func countNodes(v cue.Value) (n int) {
+	switch op, a := v.Expr(); op {
+	case cue.OrOp, cue.AndOp:
+		for _, v := range a {
+			n += countNodes(v)
+		}
+		n += len(a) - 1
+	default:
+		switch v.Kind() {
+		case cue.ListKind:
+			for i, _ := v.List(); i.Next(); {
+				n += countNodes(i.Value())
+			}
+		case cue.StructKind:
+			for i, _ := v.Fields(); i.Next(); {
+				n += countNodes(i.Value()) + 1
+			}
+		}
+	}
+	return n + 1
+}
+
+// isConcrete reports whether v is concrete and not a struct (recursively).
+// structs are not supported as the result of a struct enum depends on how
+// conjunctions and disjunctions are distributed. We could consider still doing
+// this if we define a normal form.
+func isConcrete(v cue.Value) bool {
+	if !v.IsConcrete() {
+		return false
+	}
+	if v.Kind() == cue.StructKind {
+		return false // TODO: handle struct kinds
+	}
+	for list, _ := v.List(); list.Next(); {
+		if !isConcrete(list.Value()) {
+			return false
+		}
+	}
+	return true
+}
+
+func (b *builder) disjunction(a []cue.Value, f typeFunc) {
+	disjuncts := []cue.Value{}
+	enums := []interface{}{} // TODO: unique the enums
+	nullable := false        // Only supported in OpenAPI, not JSON schema
+
+	for _, v := range a {
+		switch {
+		case v.Null() == nil:
+			// TODO: for JSON schema, we need to fall through.
+			nullable = true
+
+		case isConcrete(v):
+			enums = append(enums, decode(v))
+
+		default:
+			disjuncts = append(disjuncts, v)
+		}
+	}
+
+	// Only one conjunct?
+	if len(disjuncts) == 0 || (len(disjuncts) == 1 && len(enums) == 0) {
+		if len(disjuncts) == 1 {
+			b.value(disjuncts[0], f)
+		}
+		if len(enums) > 0 {
+			b.set("enum", enums)
+		}
+		if nullable {
+			b.set("nullable", true)
+		}
+		return
+	}
+
+	b.addConjunct(func(b *builder) {
+		anyOf := []*oaSchema{}
+		if len(enums) > 0 {
+			anyOf = append(anyOf, b.kv("enum", enums))
+		}
+
+		for _, v := range disjuncts {
+			c := newOASBuilder(b)
+			c.value(v, f)
+			anyOf = append(anyOf, c.finish())
+		}
+
+		b.set("anyOf", anyOf)
+		if nullable {
+			b.set("nullable", true)
+		}
+	})
+}
+
+func (b *builder) dispatch(f typeFunc, v cue.Value) {
+	if f != nil {
+		f(b, v)
+		return
+	}
+
+	switch v.IncompleteKind() &^ cue.BottomKind {
+	case cue.NullKind:
+		// TODO: for JSON schema we would set the type here. For OpenAPI,
+		// it must be nullable.
+		b.set("nullable", true)
+
+	case cue.BoolKind:
+		b.setType("boolean", "")
+		// No need to call.
+
+	case cue.FloatKind, cue.NumberKind:
+		// TODO:
+		// Common   Name	type	format	Comments
+		// float	number	float
+		// double	number	double
+		b.setType("number", "") // may be overridden to integer
+		b.number(v)
+
+	case cue.IntKind:
+		// integer	integer	int32	signed 	32 bits
+		// long		integer	int64	signed 	64 bits
+		b.setType("integer", "") // may be overridden to integer
+		b.number(v)
+
+	case cue.BytesKind:
+		// byte		string	byte	base64 	encoded characters
+		// binary	string	binary	any 	sequence of octets
+		b.setType("string", "byte")
+		b.bytes(v)
+	case cue.StringKind:
+		// date		string			date	   As defined by full-date - RFC3339
+		// dateTime	string			date-time  As defined by date-time - RFC3339
+		// password	string			password   A hint to UIs to obscure input
+		b.setType("string", "")
+		b.string(v)
+	case cue.StructKind:
+		b.setType("object", "")
+		b.object(v)
+	case cue.ListKind:
+		b.setType("array", "")
+		b.array(v)
+	}
+}
+
+// object supports the following
+// - maxProperties: maximum allowed fields in this struct.
+// - minProperties: minimum required fields in this struct.a
+// - patternProperties: [regexp]: schema
+//   TODO: we can support this once .kv(key, value) allow
+//      foo [=~"pattern"]: type
+//      An instance field must match all schemas for which a regexp matches.
+//   Even though it is not supported in OpenAPI, we should still accept it
+//   when receiving from OpenAPI. We could possibly use disjunctions to encode
+//   this.
+// - dependencies: what?
+// - propertyNames: schema
+//   every property name in the enclosed schema matches that of
+func (b *builder) object(v cue.Value) {
+	// TODO: discriminator objects: we could theoretically derive discriminator
+	// objects automatically: for every object in a oneOf/allOf/anyOf, or any
+	// object composed of the same type, if a property is required and set to a
+	// constant value for each type, it is a discriminator.
+
+	required := []string{}
+	for i, _ := v.Fields(cue.Optional(false), cue.Hidden(false)); i.Next(); {
+		required = append(required, i.Label())
+	}
+	if len(required) > 0 {
+		b.set("required", required)
+	}
+
+	properties := map[string]*oaSchema{}
+	for i, _ := v.Fields(cue.Optional(true), cue.Hidden(false)); i.Next(); {
+		properties[i.Label()] = b.schema(i.Value())
+	}
+	if len(properties) > 0 {
+		b.set("properties", properties)
+	}
+
+	if t, ok := v.Elem(); ok {
+		b.set("additionalProperties", b.schema(t))
+	}
+
+	// TODO: maxProperties, minProperties: can be done once we allow cap to
+	// unify with structs.
+}
+
+// List constraints:
+//
+// Max and min items.
+// - maxItems: int (inclusive)
+// - minItems: int (inclusive)
+// - items (item type)
+//   schema: applies to all items
+//   array of schemas:
+//       schema at pos must match if both value and items are defined.
+// - additional items:
+//   schema: where items must be an array of schemas, intstance elements
+//   succeed for if they match this value for any value at a position
+//   greater than that covered by items.
+// - uniqueItems: bool
+//   TODO: support with list.Unique() unique() or comprehensions.
+//   For the latter, we need equality for all values, which is doable,
+//   but not done yet.
+//
+// NOT SUPPORTED IN OpenAPI:
+// - contains:
+//   schema: an array instance is valid if at least one element matches
+//   this schema.
+func (b *builder) array(v cue.Value) {
+	// Possible conjuncts:
+	//   - one list (CUE guarantees merging all conjuncts)
+	//   - no cap: is unified with list
+	//   - unique items: at most one, but idempotent if multiple.
+	// There is never a need for allOf or anyOf. Note that a CUE list
+	// corresponds almost one-to-one to OpenAPI lists.
+	items := []*oaSchema{}
+	for i, _ := v.List(); i.Next(); {
+		items = append(items, b.schema(i.Value()))
+	}
+	if len(items) > 0 {
+		// TODO: per-item schema are not allowed in OpenAPI, only in JSON Schema.
+		// Perhaps we should turn this into an OR after first normalizing
+		// the entries.
+		b.set("items", items)
+		// panic("per-item types not supported in OpenAPI")
+	}
+
+	// TODO:
+	// A CUE cap can be a set of discontinuous ranges. If we encounter this,
+	// we can create an allOf(list type, anyOf(ranges)).
+	cap := v.Len()
+	hasMax := false
+	maxLength := int64(math.MaxInt64)
+
+	if n, capErr := cap.Int64(); capErr == nil {
+		maxLength = n
+		hasMax = true
+	} else {
+		b.value(cap, (*builder).listCap)
+	}
+
+	if !hasMax || int64(len(items)) < maxLength {
+		if typ, ok := v.Elem(); ok {
+			t := b.schema(typ)
+			if len(items) > 0 {
+				b.set("additionalItems", t)
+			} else {
+				b.set("items", t)
+			}
+		}
+	}
+}
+
+func (b *builder) listCap(v cue.Value) {
+	switch op, a := v.Expr(); op {
+	case cue.LessThanOp:
+		b.set("maxItems", b.int(a[0])-1)
+	case cue.LessThanEqualOp:
+		b.set("maxItems", b.int(a[0]))
+	case cue.GreaterThanOp:
+		b.set("minItems", b.int(a[0])+1)
+	case cue.GreaterThanEqualOp:
+		if b.int(a[0]) > 0 {
+			b.set("minItems", b.int(a[0]))
+		}
+	case cue.NoOp:
+		// must be type, so okay.
+	case cue.NotEqualOp:
+		i := b.int(a[0])
+		b.setNot("allOff", []*oaSchema{
+			b.kv("minItems", i),
+			b.kv("maxItems", i),
+		})
+
+	default:
+		panic(fmt.Sprintf("unsupported op for list capacity %v", op))
+	}
+}
+
+func (b *builder) number(v cue.Value) {
+	// Multiple conjuncts mostly means just additive constraints.
+	// Type may be number of float.
+	// TODO: deterimine integer kind.
+	// if v.IsInt() {
+	// 	b.typ = "integer"
+	// }
+
+	switch op, a := v.Expr(); op {
+	// TODO: support the following JSON schema constraints
+	// - multipleOf
+	// setIntConstraint(t, "multipleOf", a)
+
+	case cue.LessThanOp:
+		b.set("exclusiveMaximum", b.int(a[0]))
+
+	case cue.LessThanEqualOp:
+		b.set("maximum", b.int(a[0]))
+
+	case cue.GreaterThanOp:
+		b.set("exclusiveMinimum", b.int(a[0]))
+
+	case cue.GreaterThanEqualOp:
+		b.set("minimum", b.int(a[0]))
+
+	case cue.NotEqualOp:
+		i := b.int(a[0])
+		b.setNot("allOff", []*oaSchema{
+			b.kv("minItems", i),
+			b.kv("maxItems", i),
+		})
+
+	case cue.NoOp:
+		// TODO: extract format from specific type.
+
+	default:
+		// panic(fmt.Sprintf("unsupported of %v for number type", op))
+	}
+}
+
+// Multiple Regexp conjuncts are represented as allOf all other
+// constraints can be combined unless in the even of discontinuous
+// lengths.
+
+// string supports the following options:
+//
+// - maxLenght (Unicode codepoints)
+// - minLenght (Unicode codepoints)
+// - pattern (a regexp)
+//
+// The regexp pattern is as follows, and is limited to be a  strict subset of RE2:
+// Ref: https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-3.3
+//
+// JSON schema requires ECMA 262 regular expressions, but
+// limited to the following constructs:
+//   - simple character classes: [abc]
+//   - range character classes: [a-z]
+//   - complement character classes: [^abc], [^a-z]
+//   - simple quantifiers: +, *, ?, and lazy versions +? *? ??
+//   - range quantifiers: {x}, {x,y}, {x,}, {x}?, {x,y}?, {x,}?
+//   - begin and end anchors: ^ and $
+//   - simple grouping: (...)
+//   - alteration: |
+// This is a subset of RE2 used by CUE.
+//
+// Most notably absent:
+//   - the '.' for any character (not sure if that is a doc bug)
+//   - character classes \d \D [[::]] \pN \p{Name} \PN \P{Name}
+//   - word boundaries
+//   - capturing directives.
+//   - flag setting
+//   - comments
+//
+// The capturing directives and comments can be removed without
+// compromising the meaning of the regexp (TODO). Removing
+// flag setting will be tricky. Unicode character classes,
+// boundaries, etc can be compiled into simple character classes,
+// although the resulting regexp will look cumbersome.
+//
+func (b *builder) string(v cue.Value) {
+	switch op, a := v.Expr(); op {
+
+	case cue.RegexMatchOp, cue.NotRegexMatchOp:
+		s, err := a[0].String()
+		if err != nil {
+			// TODO: this may be an unresolved interpolation or expression. Consider
+			// whether it is reasonable to treat unevaluated operands as wholes and
+			// generate a compound regular expression.
+			panic(err)
+		}
+		if op == cue.RegexMatchOp {
+			b.set("pattern", s)
+		} else {
+			b.setNot("pattern", s)
+		}
+
+		// TODO: support the following JSON schema constraints
+		// - maxLength
+		// - minLength
+
+	case cue.NoOp:
+		// TODO: determine formats from specific types.
+
+	default:
+		panic(fmt.Sprintf("unsupported of %v for bytes type", op))
+	}
+}
+
+func (b *builder) bytes(v cue.Value) {
+	switch op, a := v.Expr(); op {
+
+	case cue.RegexMatchOp, cue.NotRegexMatchOp:
+		s, err := a[0].Bytes()
+		if err != nil {
+			// TODO: this may be an unresolved interpolation or expression. Consider
+			// whether it is reasonable to treat unevaluated operands as wholes and
+			// generate a compound regular expression.
+			panic(err)
+		}
+
+		if op == cue.RegexMatchOp {
+			b.set("pattern", s)
+		} else {
+			b.setNot("pattern", s)
+		}
+
+		// TODO: support the following JSON schema constraints
+		// - maxLength
+		// - minLength
+
+	case cue.NoOp:
+
+	default:
+		panic(fmt.Sprintf("unsupported of %v for bytes type", op))
+	}
+}
+
+type builder struct {
+	ctx     *buildContext
+	typ     string
+	format  string
+	current *oaSchema
+	allOf   []*oaSchema
+	enums   []interface{}
+}
+
+func newRootBuilder(c *buildContext) *builder {
+	return &builder{ctx: c}
+}
+
+func newOASBuilder(parent *builder) *builder {
+	b := &builder{
+		ctx:    parent.ctx,
+		typ:    parent.typ,
+		format: parent.format,
+	}
+	return b
+}
+
+func (b *builder) setType(t, format string) {
+	if b.typ == "" {
+		b.typ = t
+		b.format = format
+	}
+}
+
+func setType(t *oaSchema, b *builder) {
+	if b.typ != "" {
+		t.Set("type", b.typ)
+		if b.format != "" {
+			t.Set("format", b.format)
+		}
+	}
+}
+
+func (b *builder) set(key string, v interface{}) {
+	if b.current == nil {
+		b.current = &orderedMap{}
+		b.allOf = append(b.allOf, b.current)
+		setType(b.current, b)
+	} else if b.current.Exists(key) {
+		b.current = &orderedMap{}
+		b.allOf = append(b.allOf, b.current)
+	}
+	b.current.Set(key, v)
+}
+
+func (b *builder) kv(key string, value interface{}) *oaSchema {
+	constraint := &orderedMap{}
+	setType(constraint, b)
+	constraint.Set(key, value)
+	return constraint
+}
+
+func (b *builder) setNot(key string, value interface{}) {
+	not := &orderedMap{}
+	not.Set("not", b.kv(key, value))
+	b.add(not)
+}
+
+func (b *builder) finish() *oaSchema {
+	switch len(b.allOf) {
+	case 0:
+		if b.typ == "" {
+			panic("no type specified at finish")
+		}
+		t := &orderedMap{}
+		setType(t, b)
+		return t
+
+	case 1:
+		setType(b.allOf[0], b)
+		return b.allOf[0]
+
+	default:
+		t := &orderedMap{}
+		t.Set("allOf", b.allOf)
+		return t
+	}
+}
+
+func (b *builder) add(t *oaSchema) {
+	b.allOf = append(b.allOf, t)
+}
+
+func (b *builder) addConjunct(f func(*builder)) {
+	c := newOASBuilder(b)
+	f(c)
+	b.add(c.finish())
+}
+
+func (b *builder) addRef(ref []string) {
+	// TODO: validate path.
+	// TODO: map CUE types to OAPI types.
+	b.addConjunct(func(b *builder) {
+		a := append([]string{"#", b.ctx.refPrefix}, ref...)
+		b.set("$ref", path.Join(a...))
+	})
+}
+
+func (b *builder) int(v cue.Value) int64 {
+	i, err := v.Int64()
+	if err != nil {
+		panic("could not retrieve int")
+	}
+	return i
+}
+
+func decode(v cue.Value) interface{} {
+	var d interface{}
+	if err := v.Decode(&d); err != nil {
+		panic(err)
+	}
+	return d
+}
