Starlark
A small, deterministic, hermetic dialect of Python designed as a configuration language for the Bazel and Buck build systems
Created by Google (Bazel team): Ulf Adams, Lukács Berki, Jon Brandvein, John Field, Laurent Le Brun, Dmitry Lomov, Damien Martin-Guillerez, Vladimir Moskva, and Florian Weikert
Starlark is a small, deterministic dialect of Python designed to serve as a configuration and extension language. Its syntax is a strict subset of Python’s, but its semantics are deliberately restricted so that programs are safe to execute, reproducible, and easy to reason about at scale. Originally created for Google’s Bazel build system — and later adopted by Meta’s Buck — Starlark is best understood as the language that build systems use to describe what to build and how to build it, without allowing builds to reach out to the network, the clock, or arbitrary parts of the file system.
A note on dating
The encyclopedia metadata lists 2015 as Starlark’s first-appearance year, corresponding to its debut as Skylark, the extension language embedded in the Java implementation of Bazel when Google open-sourced it. A standalone Go implementation of the language followed around 2017, and the name Starlark was adopted in 2018 to signal that the language was useful beyond Bazel. This page therefore uses 2015 as the first-appearance year and treats 2017 (the Go implementation) as a significant milestone rather than the origin. Where an exact date is uncertain, dates below should be read as approximate.
History & Origins
Starlark grew out of the need for a build system that could scale to Google-sized repositories while remaining fast and reproducible. When Google released Bazel as open source in 2015, it included an embedded language — code-named Skylark — for writing BUILD files and for extending the build system with custom rules. Skylark was designed and implemented in Java by a team on the Bazel project, including Ulf Adams, Lukács Berki, Jon Brandvein, John Field, Laurent Le Brun, Dmitry Lomov, Damien Martin-Guillerez, Vladimir Moskva, and Florian Weikert, drawing heavily on the design of Python.
Because the language proved useful outside of build files, a separate implementation in Go was developed (around 2017), first under google/skylark and later at go.starlark.net, allowing any application to embed the language. In 2018, the project settled on the name Starlark. Later, Meta created a Rust implementation, starlark-rust, announced in 2021, which underpins the Buck and Buck2 build systems. Today the language is defined by a shared specification with three main implementations — Java, Go, and Rust — rather than a single reference release.
Design Philosophy
Starlark’s design is shaped by a single overriding goal: make build and configuration code that is trustworthy at scale. To that end it enforces three properties that distinguish it sharply from general-purpose Python:
- Deterministic evaluation. Running the same code twice produces the same result. Dictionaries and sets iterate in a defined order, and there are no sources of nondeterminism baked into the language.
- Hermetic execution. Starlark code cannot access the file system, the network, or the system clock. This makes it safe to evaluate untrusted code and ensures that a build’s inputs are fully declared rather than discovered at runtime.
- Parallel, thread-safe evaluation. Modules can be loaded in parallel. To keep shared data safe, values become frozen (immutable) once a module finishes loading, so no two threads can mutate the same state.
The result is a language that looks like Python — indentation-based blocks, familiar literals, list comprehensions — but is intentionally missing features that would undermine those guarantees.
Key Features
- Python-subset syntax. Starlark’s grammar is a strict subset of Python’s, so tools that parse Python’s AST can often read Starlark files, and Python programmers feel immediately at home.
- High-level data types. It includes integers, strings, booleans, lists, dictionaries, tuples, and sets, plus first-class functions with lexical scoping and garbage collection.
- The
load()statement. Files import symbols from other files withload("//path:file.bzl", "symbol"), giving a controlled, explicit module system. - Freezing / immutability. After a module is loaded, its values are frozen, guaranteeing that later code cannot mutate shared state — the mechanism behind safe parallel loading.
- Deliberate omissions. To preserve determinism and hermeticity, Starlark drops features found in Python such as
whileloops (in most dialects), recursion, classes, exceptions,importof arbitrary modules, and I/O.
A taste of the syntax
| |
| |
The code reads like ordinary Python, but there is no way for it to open a file, make a network call, or read the clock — everything it can affect is the build graph it is helping to describe.
Evolution
Starlark has evolved less through numbered releases and more through implementations and specification. Its three principal implementations serve different ecosystems:
| Implementation | Language | Primary use | First appeared |
|---|---|---|---|
| Bazel’s built-in interpreter | Java | Bazel BUILD / .bzl files | 2015 (as Skylark) |
go.starlark.net (formerly google/skylark) | Go | Embedding in Go applications | ~2017 |
starlark-rust | Rust | Buck / Buck2 build systems | ~2021 |
A shared language specification in the bazelbuild/starlark repository aims to keep these implementations compatible. Individual dialects differ in small ways — some add optional features like while loops, recursion, or floating-point numbers — but the deterministic, hermetic core remains constant.
Current Relevance
Starlark is very much a living language, though a specialized one. It is the configuration language for two of the most significant large-scale build systems in industry: Bazel (widely used at Google and across the open-source world) and Buck2 (Meta’s Rust-based build system, open-sourced in 2023). Beyond builds, the embeddable Go and Rust implementations have made Starlark a popular choice whenever a project needs a safe, sandboxed scripting language for user-supplied configuration — tools like Tilt, skycfg, and Isopod use it to replace sprawling YAML with real code that has functions, variables, and loops but cannot do anything dangerous.
Why It Matters
Starlark represents a compelling answer to a recurring problem: static configuration formats like YAML and JSON are too limited, but a full programming language is too dangerous and too unpredictable to embed. By taking Python’s friendly, widely-understood syntax and stripping away everything that would make evaluation nondeterministic or unsafe, Starlark carves out a middle path — “configuration as code” that remains reproducible, parallelizable, and safe to run on untrusted input. Its adoption by both Google’s Bazel and Meta’s Buck, and its reimplementation in Go and Rust, show how a carefully constrained language can outgrow the single tool it was built for and become a small standard in its own right.
Timeline
Notable Uses & Legacy
Bazel
Google's open-source build and test system uses Starlark for its BUILD files (which declare targets like libraries, binaries, and tests) and for .bzl extension files that define custom rules and macros
Buck2 (Meta)
Meta's Rust-based successor to Buck uses the starlark-rust implementation to evaluate BUILD files and define build rules, relying on Starlark's determinism for large-scale, reproducible builds
Tilt
The Tilt developer tool for Kubernetes uses Starlark (in Tiltfiles) to describe how to build and deploy microservices during local development
Configuration and policy tooling
Projects such as skycfg and Isopod embed Starlark to generate configuration (for example Kubernetes or protobuf configs) using real functions and loops instead of static YAML
Embeddable scripting via go.starlark.net
The Go implementation is embedded by a range of applications that want a safe, sandboxed scripting language for user-supplied configuration and logic