diff --git a/internal/core/convert/go.go b/internal/core/convert/go.go
index 1997136..6e74b9d 100644
--- a/internal/core/convert/go.go
+++ b/internal/core/convert/go.go
@@ -224,7 +224,7 @@
 func convertRec(ctx *adt.OpContext, nilIsTop bool, x interface{}) adt.Value {
 	if internal.CoreValue != nil {
 		if ii, iv := internal.CoreValue(x); ii != nil {
-			i := ii.(*runtime.Index)
+			i := ii.(*runtime.Runtime)
 			v := iv.(*adt.Vertex)
 			// TODO: panic if nto the same runtime.
 			_ = i
diff --git a/internal/core/runtime/build.go b/internal/core/runtime/build.go
new file mode 100644
index 0000000..c167e16
--- /dev/null
+++ b/internal/core/runtime/build.go
@@ -0,0 +1,94 @@
+// Copyright 2020 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 runtime
+
+import (
+	"strings"
+
+	"cuelang.org/go/cue/ast"
+	"cuelang.org/go/cue/ast/astutil"
+	"cuelang.org/go/cue/build"
+	"cuelang.org/go/cue/errors"
+	"cuelang.org/go/internal/core/adt"
+	"cuelang.org/go/internal/core/compile"
+)
+
+// Build builds b and all its transitive dependencies, insofar they have not
+// been build yet.
+func (x *Runtime) Build(b *build.Instance) (v *adt.Vertex, errs errors.Error) {
+	if v := x.GetNodeFromInstance(b); v != nil {
+		return v, b.Err
+	}
+	// TODO: clear cache of old implementation.
+	// if s := b.ImportPath; s != "" {
+	// 	// Use cached result, if available.
+	// 	if v, err := x.LoadImport(s); v != nil || err != nil {
+	// 		return v, err
+	// 	}
+	// }
+
+	errs = b.Err
+
+	// Build transitive dependencies.
+	for _, file := range b.Files {
+		file.VisitImports(func(d *ast.ImportDecl) {
+			for _, s := range d.Specs {
+				errs = errors.Append(errs, x.buildSpec(b, s))
+			}
+		})
+	}
+
+	err := x.ResolveFiles(b)
+	errs = errors.Append(errs, err)
+
+	v, err = compile.Files(nil, x, b.ID(), b.Files...)
+	errs = errors.Append(errs, err)
+
+	if errs != nil {
+		v = adt.ToVertex(&adt.Bottom{Err: errs})
+		b.Err = errs
+	}
+
+	x.AddInst(b.ImportPath, v, b)
+
+	return v, errs
+}
+
+func (x *Runtime) buildSpec(b *build.Instance, spec *ast.ImportSpec) (errs errors.Error) {
+	info, err := astutil.ParseImportSpec(spec)
+	if err != nil {
+		return errors.Promote(err, "invalid import path")
+	}
+
+	pkg := b.LookupImport(info.ID)
+	if pkg == nil {
+		if strings.Contains(info.ID, ".") {
+			return errors.Newf(spec.Pos(),
+				"package %q imported but not defined in %s",
+				info.ID, b.ImportPath)
+		}
+		return nil // TODO: check the builtin package exists here.
+	}
+
+	if v := x.index.importsByBuild[pkg]; v != nil {
+		return pkg.Err
+	}
+
+	if _, err := x.Build(pkg); err != nil {
+		return err
+	}
+
+	return nil
+}
diff --git a/internal/core/runtime/go.go b/internal/core/runtime/go.go
new file mode 100644
index 0000000..4b84b3f
--- /dev/null
+++ b/internal/core/runtime/go.go
@@ -0,0 +1,53 @@
+// Copyright 2020 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 runtime
+
+import (
+	"reflect"
+
+	"cuelang.org/go/cue/ast"
+	"cuelang.org/go/internal/core/adt"
+)
+
+func (x *Runtime) StoreType(t reflect.Type, src ast.Expr, expr adt.Expr) {
+	if expr == nil {
+		x.index.StoreType(t, src)
+	} else {
+		x.index.StoreType(t, expr)
+	}
+}
+
+func (x *Runtime) LoadType(t reflect.Type) (src ast.Expr, expr adt.Expr, ok bool) {
+	v, ok := x.index.LoadType(t)
+	if ok {
+		switch x := v.(type) {
+		case ast.Expr:
+			return x, nil, true
+		case adt.Expr:
+			src, _ = x.Source().(ast.Expr)
+			return src, x, true
+		}
+	}
+	return nil, nil, false
+}
+
+func (x *index) StoreType(t reflect.Type, v interface{}) {
+	x.typeCache.Store(t, v)
+}
+
+func (x *index) LoadType(t reflect.Type) (v interface{}, ok bool) {
+	v, ok = x.typeCache.Load(t)
+	return v, ok
+}
diff --git a/internal/core/runtime/imports.go b/internal/core/runtime/imports.go
new file mode 100644
index 0000000..4f25c96
--- /dev/null
+++ b/internal/core/runtime/imports.go
@@ -0,0 +1,128 @@
+// Copyright 2020 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 runtime
+
+import (
+	"path"
+	"sync"
+
+	"cuelang.org/go/cue/build"
+	"cuelang.org/go/cue/errors"
+	"cuelang.org/go/internal/core/adt"
+)
+
+type PackageFunc func(ctx adt.Runtime) (*adt.Vertex, errors.Error)
+
+func RegisterBuiltin(importPath string, f PackageFunc) {
+	sharedIndex.RegisterBuiltin(importPath, f)
+}
+
+func (x *index) RegisterBuiltin(importPath string, f PackageFunc) {
+	if x.builtins == nil {
+		x.builtins = map[string]PackageFunc{}
+	}
+	x.builtins[importPath] = f
+}
+
+var SharedRuntime = &Runtime{index: sharedIndex}
+
+func (x *Runtime) IsBuiltinPackage(path string) bool {
+	return x.index.isBuiltin(path)
+}
+
+// sharedIndex is used for indexing builtins and any other labels common to
+// all instances.
+var sharedIndex = newIndex()
+
+// index maps conversions from label names to internal codes.
+//
+// All instances belonging to the same package should share this index.
+type index struct {
+	// Change this to Instance at some point.
+	// From *structLit/*Vertex -> Instance
+	imports        map[*adt.Vertex]*build.Instance
+	importsByPath  map[string]*adt.Vertex
+	importsByBuild map[*build.Instance]*adt.Vertex
+	builtins       map[string]PackageFunc
+
+	// mutex     sync.Mutex
+	typeCache sync.Map // map[reflect.Type]evaluated
+
+}
+
+func newIndex() *index {
+	i := &index{
+		imports:        map[*adt.Vertex]*build.Instance{},
+		importsByPath:  map[string]*adt.Vertex{},
+		importsByBuild: map[*build.Instance]*adt.Vertex{},
+	}
+	return i
+}
+
+func (x *index) isBuiltin(id string) bool {
+	if x == nil || x.builtins == nil {
+		return false
+	}
+	_, ok := x.builtins[id]
+	return ok
+}
+
+func (r *Runtime) AddInst(path string, key *adt.Vertex, p *build.Instance) {
+	x := r.index
+	if key == nil {
+		panic("key must not be nil")
+	}
+	x.imports[key] = p
+	x.importsByBuild[p] = key
+	if path != "" {
+		x.importsByPath[path] = key
+	}
+}
+
+func (r *Runtime) GetInstanceFromNode(key *adt.Vertex) *build.Instance {
+	return r.index.imports[key]
+}
+
+func (r *Runtime) GetNodeFromInstance(key *build.Instance) *adt.Vertex {
+	return r.index.importsByBuild[key]
+}
+
+func (r *Runtime) LoadImport(importPath string) (*adt.Vertex, errors.Error) {
+	x := r.index
+
+	key := x.importsByPath[importPath]
+	if key != nil {
+		return key, nil
+	}
+
+	if x.builtins != nil {
+		if f := x.builtins[importPath]; f != nil {
+			p, err := f(r)
+			if err != nil {
+				return adt.ToVertex(&adt.Bottom{Err: err}), nil
+			}
+			inst := &build.Instance{
+				ImportPath: importPath,
+				PkgName:    path.Base(importPath),
+			}
+			x.imports[p] = inst
+			x.importsByPath[importPath] = p
+			x.importsByBuild[inst] = p
+			return p, nil
+		}
+	}
+
+	return key, nil
+}
diff --git a/internal/core/runtime/index.go b/internal/core/runtime/index.go
index a8e381c..bf5867c 100644
--- a/internal/core/runtime/index.go
+++ b/internal/core/runtime/index.go
@@ -15,122 +15,30 @@
 package runtime
 
 import (
-	"reflect"
 	"sync"
 
-	"cuelang.org/go/cue/ast"
 	"cuelang.org/go/internal"
 	"cuelang.org/go/internal/core/adt"
 )
 
-// Index maps conversions from label names to internal codes.
-//
-// All instances belonging to the same package should share this Index.
-//
-// INDEX IS A TRANSITIONAL TYPE TO BRIDGE THE OLD AND NEW
-// IMPLEMENTATIONS. USE RUNTIME.
-type Index struct {
-	labelMap map[string]int64
-	labels   []string
-
-	// Change this to Instance at some point.
-	// From *structLit/*Vertex -> Instance
-	imports       map[interface{}]interface{}
-	importsByPath map[string]interface{}
-	// imports map[string]*adt.Vertex
-
-	offset int64
-	parent *Index
-
-	// mutex     sync.Mutex
-	typeCache sync.Map // map[reflect.Type]evaluated
+func (r *Runtime) IndexToString(i int64) string {
+	return r.index.IndexToString(i)
 }
 
-// SharedIndex is used for indexing builtins and any other labels common to
-// all instances.
-var SharedIndex = newSharedIndex()
-
-var SharedIndexNew = newSharedIndex()
-
-var SharedRuntimeNew = &Runtime{index: SharedIndexNew}
-
-func newSharedIndex() *Index {
-	i := &Index{
-		labelMap:      map[string]int64{"": 0},
-		labels:        []string{""},
-		imports:       map[interface{}]interface{}{},
-		importsByPath: map[string]interface{}{},
-	}
-	return i
+func (r *Runtime) StringToIndex(s string) int64 {
+	return getKey(s)
 }
 
-// NewIndex creates a new index.
-func NewIndex(parent *Index) *Index {
-	i := &Index{
-		labelMap:      map[string]int64{},
-		imports:       map[interface{}]interface{}{},
-		importsByPath: map[string]interface{}{},
-		offset:        int64(len(parent.labels)) + parent.offset,
-		parent:        parent,
-	}
-	return i
+func (r *Runtime) LabelStr(l adt.Feature) string {
+	return l.IdentString(r)
 }
 
-func (x *Index) IndexToString(i int64) string {
-	for ; i < x.offset; x = x.parent {
-	}
-	return x.labels[i-x.offset]
+func (r *Runtime) StrLabel(str string) adt.Feature {
+	return r.Label(str, false)
 }
 
-func (x *Index) StringToIndex(s string) int64 {
-	for p := x; p != nil; p = p.parent {
-		if f, ok := p.labelMap[s]; ok {
-			return int64(f)
-		}
-	}
-	index := int64(len(x.labelMap)) + x.offset
-	x.labelMap[s] = index
-	x.labels = append(x.labels, s)
-	return int64(index)
-}
-
-func (x *Index) HasLabel(s string) (ok bool) {
-	for c := x; c != nil; c = c.parent {
-		_, ok = c.labelMap[s]
-		if ok {
-			break
-		}
-	}
-	return ok
-}
-
-func (x *Index) StoreType(t reflect.Type, v interface{}) {
-	x.typeCache.Store(t, v)
-}
-
-func (x *Index) LoadType(t reflect.Type) (v interface{}, ok bool) {
-	v, ok = x.typeCache.Load(t)
-	return v, ok
-}
-
-func (x *Index) StrLabel(str string) adt.Feature {
-	return x.Label(str, false)
-}
-
-func (x *Index) NodeLabel(n ast.Node) (f adt.Feature, ok bool) {
-	switch label := n.(type) {
-	case *ast.BasicLit:
-		name, _, err := ast.LabelName(label)
-		return x.Label(name, false), err == nil
-	case *ast.Ident:
-		name, err := ast.ParseIdent(label)
-		return x.Label(name, true), err == nil
-	}
-	return 0, false
-}
-
-func (x *Index) Label(s string, isIdent bool) adt.Feature {
-	index := x.StringToIndex(s)
+func (r *Runtime) Label(s string, isIdent bool) adt.Feature {
+	index := r.StringToIndex(s)
 	typ := adt.StringLabel
 	if isIdent {
 		switch {
@@ -146,32 +54,39 @@
 	return f
 }
 
-func (idx *Index) LabelStr(l adt.Feature) string {
-	return l.IdentString(idx)
+// TODO: move to Runtime as fields.
+var (
+	labelMap = map[string]int{}
+	labels   = make([]string, 0, 1000)
+	mutex    sync.RWMutex
+)
+
+func init() {
+	getKey("")
 }
 
-func (x *Index) AddInst(path string, key, p interface{}) {
-	if key == nil {
-		panic("key must not be nil")
+func getKey(s string) int64 {
+	mutex.RLock()
+	p, ok := labelMap[s]
+	mutex.RUnlock()
+	if ok {
+		return int64(p)
 	}
-	x.imports[key] = p
-	if path != "" {
-		x.importsByPath[path] = key
+	mutex.Lock()
+	defer mutex.Unlock()
+	p, ok = labelMap[s]
+	if ok {
+		return int64(p)
 	}
+	p = len(labels)
+	labels = append(labels, s)
+	labelMap[s] = p
+	return int64(p)
 }
 
-func (x *Index) GetImportFromNode(key interface{}) interface{} {
-	imp := x.imports[key]
-	if imp == nil && x.parent != nil {
-		return x.parent.GetImportFromNode(key)
-	}
-	return imp
-}
-
-func (x *Index) GetImportFromPath(id string) interface{} {
-	key := x.importsByPath[id]
-	if key == nil && x.parent != nil {
-		return x.parent.GetImportFromPath(id)
-	}
-	return key
+func (x *index) IndexToString(i int64) string {
+	mutex.RLock()
+	s := labels[i]
+	mutex.RUnlock()
+	return s
 }
diff --git a/internal/core/runtime/resolve.go b/internal/core/runtime/resolve.go
index 29f19e4..94188db 100644
--- a/internal/core/runtime/resolve.go
+++ b/internal/core/runtime/resolve.go
@@ -23,15 +23,9 @@
 	"cuelang.org/go/cue/errors"
 )
 
-func lineStr(idx *Index, n ast.Node) string {
-	return n.Pos().String()
-}
+func (r *Runtime) ResolveFiles(p *build.Instance) (errs errors.Error) {
+	idx := r.index
 
-func ResolveFiles(
-	idx *Index,
-	p *build.Instance,
-	isBuiltin func(s string) bool,
-) (errs errors.Error) {
 	// Link top-level declarations. As top-level entries get unified, an entry
 	// may be linked to any top-level entry of any of the files.
 	allFields := map[string]ast.Node{}
@@ -45,18 +39,17 @@
 		}
 	}
 	for _, f := range p.Files {
-		err := ResolveFile(idx, f, p, allFields, isBuiltin)
+		err := resolveFile(idx, f, p, allFields)
 		errs = errors.Append(errs, err)
 	}
 	return errs
 }
 
-func ResolveFile(
-	idx *Index,
+func resolveFile(
+	idx *index,
 	f *ast.File,
 	p *build.Instance,
 	allFields map[string]ast.Node,
-	isBuiltin func(s string) bool,
 ) errors.Error {
 	unresolved := map[string][]*ast.Ident{}
 	for _, u := range f.Unresolved {
@@ -82,7 +75,7 @@
 		name := path.Base(id)
 		if imp := p.LookupImport(id); imp != nil {
 			name = imp.PkgName
-		} else if !isBuiltin(id) {
+		} else if _, ok := idx.builtins[id]; !ok {
 			errs = errors.Append(errs,
 				nodeErrorf(spec, "package %q not found", id))
 			continue
@@ -162,3 +155,7 @@
 	// }
 	return errs
 }
+
+func lineStr(idx *index, n ast.Node) string {
+	return n.Pos().String()
+}
diff --git a/internal/core/runtime/resolve_test.go b/internal/core/runtime/resolve_test.go
index 42ec1dd..9bc7240 100644
--- a/internal/core/runtime/resolve_test.go
+++ b/internal/core/runtime/resolve_test.go
@@ -33,8 +33,6 @@
 		Path: ast.NewString(importPath),
 	}
 
-	isBuiltin := func(s string) bool { return false }
-
 	f := &ast.File{
 		Decls: []ast.Decl{
 			&ast.ImportDecl{Specs: []*ast.ImportSpec{spec1, spec2}},
@@ -50,12 +48,12 @@
 		Imports: []*ast.ImportSpec{spec1, spec2},
 	}
 
-	err := ResolveFile(nil, f, &build.Instance{
+	err := resolveFile(nil, f, &build.Instance{
 		Imports: []*build.Instance{{
 			ImportPath: importPath,
 			PkgName:    "foo",
 		}},
-	}, map[string]ast.Node{}, isBuiltin)
+	}, map[string]ast.Node{})
 
 	if err != nil {
 		t.Errorf("exected no error, found %v", err)
diff --git a/internal/core/runtime/runtime.go b/internal/core/runtime/runtime.go
index 6361e6b..448dc30 100644
--- a/internal/core/runtime/runtime.go
+++ b/internal/core/runtime/runtime.go
@@ -14,124 +14,18 @@
 
 package runtime
 
-import (
-	"reflect"
-	"strings"
-
-	"cuelang.org/go/cue/ast"
-	"cuelang.org/go/cue/ast/astutil"
-	"cuelang.org/go/cue/build"
-	"cuelang.org/go/cue/errors"
-	"cuelang.org/go/internal/core/adt"
-	"cuelang.org/go/internal/core/compile"
-)
-
 // A Runtime maintains data structures for indexing and resuse for evaluation.
 type Runtime struct {
-	index *Index
+	index *index
 
 	// Data holds the legacy index strut. It is for transitional purposes only.
 	Data interface{}
 }
 
-// New creates a new Runtime.
+// New creates a new Runtime. The builtins registered with RegisterBuiltin
+// are available for
 func New() *Runtime {
 	return &Runtime{
-		index: NewIndex(SharedIndexNew),
+		index: sharedIndex,
 	}
 }
-
-func NewWithIndex(x *Index) *Runtime {
-	return &Runtime{index: x}
-}
-
-func (x *Runtime) IndexToString(i int64) string {
-	return x.index.IndexToString(i)
-}
-
-func (x *Runtime) StringToIndex(s string) int64 {
-	return x.index.StringToIndex(s)
-}
-
-func (x *Runtime) Build(b *build.Instance) (v *adt.Vertex, errs errors.Error) {
-	if s := b.ImportPath; s != "" {
-		// Use cached result, if available.
-		if v, err := x.LoadImport(s); v != nil || err != nil {
-			return v, err
-		}
-		// Cache the result if any.
-		defer func() {
-			if errs == nil && v != nil {
-				x.index.AddInst(b.ImportPath, v, b)
-			}
-		}()
-	}
-
-	// Build transitive dependencies.
-	for _, file := range b.Files {
-		file.VisitImports(func(d *ast.ImportDecl) {
-			for _, s := range d.Specs {
-				errs = errors.Append(errs, x.buildSpec(b, s))
-			}
-		})
-	}
-
-	if errs != nil {
-		return nil, errs
-	}
-
-	return compile.Files(nil, x, b.ID(), b.Files...)
-}
-
-func (x *Runtime) buildSpec(b *build.Instance, spec *ast.ImportSpec) (errs errors.Error) {
-	info, err := astutil.ParseImportSpec(spec)
-	if err != nil {
-		return errors.Promote(err, "invalid import path")
-	}
-
-	pkg := b.LookupImport(info.ID)
-	if pkg == nil {
-		if strings.Contains(info.ID, ".") {
-			return errors.Newf(spec.Pos(),
-				"package %q imported but not defined in %s",
-				info.ID, b.ImportPath)
-		}
-		return nil // TODO: check the builtin package exists here.
-	}
-
-	if _, err := x.Build(pkg); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (x *Runtime) LoadImport(importPath string) (*adt.Vertex, errors.Error) {
-	v := x.index.GetImportFromPath(importPath)
-	if v == nil {
-		return nil, nil
-	}
-	return v.(*adt.Vertex), nil
-}
-
-func (x *Runtime) StoreType(t reflect.Type, src ast.Expr, expr adt.Expr) {
-	if expr == nil {
-		x.index.StoreType(t, src)
-	} else {
-		x.index.StoreType(t, expr)
-	}
-}
-
-func (x *Runtime) LoadType(t reflect.Type) (src ast.Expr, expr adt.Expr, ok bool) {
-	v, ok := x.index.LoadType(t)
-	if ok {
-		switch x := v.(type) {
-		case ast.Expr:
-			return x, nil, true
-		case adt.Expr:
-			src, _ = x.Source().(ast.Expr)
-			return src, x, true
-		}
-	}
-	return nil, nil, false
-}
