Top Related Projects
Skylark in Go: the Skylark configuration language, implemented in Go [MOVED to go.starlark.net]
HCL is the HashiCorp configuration language.
Maintainable configuration files
Common Expression Language -- specification and binary representation
A fast build system that encourages the creation of small, reusable modules over a variety of platforms and languages.
Quick Overview
Starlark is a dialect of Python designed for use as a configuration language. It is the primary language used in Bazel build files and is also used in other tools like Buck and Pants. Starlark aims to be simple, small, and hermetic, making it suitable for configuration purposes.
Pros
- Familiar syntax for Python developers
- Deterministic evaluation, which is crucial for reproducible builds
- Designed for configuration, with limitations that prevent unintended side effects
- Extensible through custom built-in functions and types
Cons
- Limited standard library compared to full Python
- No support for certain Python features like classes or recursion
- Learning curve for developers not familiar with Python or Bazel
- Can be verbose for complex configurations
Code Examples
- Defining a simple rule:
def _impl(ctx):
output = ctx.actions.declare_file(ctx.label.name + ".txt")
ctx.actions.write(output=output, content="Hello, World!")
return [DefaultInfo(files = depset([output]))]
hello_world = rule(
implementation = _impl,
attrs = {},
)
- Using a macro to simplify rule usage:
def hello_library(name):
hello_world(
name = name + "_rule",
)
native.filegroup(
name = name,
srcs = [name + "_rule"],
)
- Loading and using external dependencies:
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "com_google_protobuf",
urls = ["https://github.com/protocolbuffers/protobuf/archive/v3.19.1.zip"],
strip_prefix = "protobuf-3.19.1",
)
Getting Started
To use Starlark in a Bazel project:
- Install Bazel: https://docs.bazel.build/versions/main/install.html
- Create a
WORKSPACE
file in your project root:
workspace(name = "my_project")
- Create a
BUILD
file in your source directory:
load("@rules_cc//cc:defs.bzl", "cc_binary")
cc_binary(
name = "hello_world",
srcs = ["hello_world.cc"],
)
- Write your Starlark code in
.bzl
files and load them in yourBUILD
files as needed.
Competitor Comparisons
Skylark in Go: the Skylark configuration language, implemented in Go [MOVED to go.starlark.net]
Pros of Skylark
- More actively maintained with recent updates and contributions
- Includes additional tools and utilities for working with Starlark
- Better documentation and examples for users
Cons of Skylark
- Less integrated with the Bazel ecosystem
- Smaller community and fewer contributors
- May have compatibility issues with some Bazel-specific features
Code Comparison
Skylark:
def my_rule_impl(ctx):
output = ctx.actions.declare_file(ctx.label.name + ".out")
ctx.actions.run_shell(
outputs=[output],
command="echo 'Hello, Skylark!' > {}".format(output.path),
)
return [DefaultInfo(files=depset([output]))]
Starlark:
def my_rule_impl(ctx):
output = ctx.actions.declare_file(ctx.label.name + ".out")
ctx.actions.run_shell(
outputs=[output],
command="echo 'Hello, Starlark!' > {}".format(output.path),
)
return [DefaultInfo(files=depset([output]))]
The code comparison shows that both implementations are nearly identical, with the main difference being the project name in the output message.
Pros of go-jsonnet
- Designed specifically for configuration management and data templating
- Supports advanced features like import statements and library functions
- Offers a more expressive and flexible syntax for complex data structures
Cons of go-jsonnet
- Less integrated with build systems compared to Starlark
- May have a steeper learning curve for users unfamiliar with JSON-based languages
- Limited use cases outside of configuration management
Code Comparison
Starlark:
def greet(name):
return "Hello, " + name + "!"
result = greet("World")
print(result)
go-jsonnet:
local greet(name) = "Hello, " + name + "!";
{
result: greet("World")
}
Summary
While Starlark is primarily designed for build system configuration and scripting, go-jsonnet focuses on data templating and configuration management. Starlark offers tighter integration with build tools like Bazel, while go-jsonnet provides more flexibility for complex data structures and configuration scenarios. The choice between the two depends on the specific use case and the ecosystem in which they'll be used.
HCL is the HashiCorp configuration language.
Pros of HCL
- More flexible syntax, allowing for both configuration and data representation
- Native support for JSON-like structures and heredocs
- Designed for human-readability and ease of use in configuration files
Cons of HCL
- Less focused on programming language features compared to Starlark
- May be less suitable for complex scripting or programming tasks
- Limited built-in functions and standard library compared to Starlark
Code Comparison
HCL:
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "ExampleInstance"
}
}
Starlark:
def create_instance(ami, instance_type, name):
return {
"ami": ami,
"instance_type": instance_type,
"tags": {"Name": name},
}
example = create_instance("ami-0c55b159cbfafe1f0", "t2.micro", "ExampleInstance")
The HCL example shows its declarative nature and built-in support for resource definitions, while the Starlark example demonstrates its more programmatic approach with functions and variable assignments.
Maintainable configuration files
Pros of dhall-lang
- Strong type system with support for dependent types, offering more advanced type-checking capabilities
- Built-in support for importing and referencing external files, enhancing modularity
- Language-agnostic design, allowing for broader application across different programming ecosystems
Cons of dhall-lang
- Steeper learning curve due to its more complex type system and functional programming concepts
- Smaller community and ecosystem compared to Starlark, potentially leading to fewer resources and tools
Code Comparison
Dhall example:
let Config = { name : Text, age : Natural }
let person = { name = "Alice", age = 30 } : Config
in person
Starlark example:
def create_person(name, age):
return {"name": name, "age": age}
person = create_person("Alice", 30)
Both examples create a simple configuration structure, but Dhall's static typing and explicit type declarations contrast with Starlark's more Python-like dynamic approach.
Common Expression Language -- specification and binary representation
Pros of cel-spec
- Designed specifically for expression evaluation in configuration and policy scenarios
- Supports gradual typing, allowing for more flexible and dynamic expressions
- Includes built-in support for protocol buffers and common data types
Cons of cel-spec
- Less mature and less widely adopted compared to Starlark
- Limited to expression evaluation, not suitable for full scripting capabilities
- Smaller ecosystem and fewer available tools and integrations
Code Comparison
cel-spec:
name.startsWith("foo") && auth.user == "admin" && request.time < now - duration("24h")
Starlark:
def check_condition(name, auth, request, now):
return (name.startswith("foo") and
auth.user == "admin" and
request.time < now - timedelta(hours=24))
Summary
cel-spec is tailored for expression evaluation in configuration and policy contexts, offering gradual typing and built-in support for common data types. However, it has a smaller ecosystem and is less mature than Starlark. Starlark, being a more complete scripting language, offers greater flexibility but may be overkill for simple expression evaluation tasks. The choice between the two depends on the specific use case and requirements of the project.
A fast build system that encourages the creation of small, reusable modules over a variety of platforms and languages.
Pros of Buck
- More comprehensive build system with advanced features like caching and distributed builds
- Supports multiple programming languages and platforms out-of-the-box
- Extensive documentation and active community support
Cons of Buck
- Steeper learning curve due to its complexity
- Heavier resource usage, especially for smaller projects
- Less flexibility in customizing build rules compared to Starlark
Code Comparison
Buck:
android_binary(
name = "app",
manifest = "AndroidManifest.xml",
keystore = ":debug_keystore",
deps = [
":app-lib",
],
)
Starlark:
android_binary(
name = "app",
manifest = "AndroidManifest.xml",
keystore = ":debug_keystore",
deps = [":app-lib"],
)
The syntax for defining build targets is similar between Buck and Starlark, with minor differences in formatting and structure. Both use a declarative approach to specify build configurations, making it relatively easy for developers familiar with one system to understand the other.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Starlark
Overview
Starlark (formerly known as Skylark) is a language intended for use as a configuration language. It was designed for the Bazel build system, but may be useful for other projects as well. This repository is where Starlark features are proposed, discussed, and specified. It contains information about the language, including the specification. There are multiple implementations of Starlark.
Starlark is a dialect of Python. Like Python, it is a dynamically typed language with high-level data types, first-class functions with lexical scope, and garbage collection. Independent Starlark threads execute in parallel, so Starlark workloads scale well on parallel machines. Starlark is a small and simple language with a familiar and highly readable syntax. You can use it as an expressive notation for structured data, defining functions to eliminate repetition, or you can use it to add scripting capabilities to an existing application.
A Starlark interpreter is typically embedded within a larger application, and the application may define additional domain-specific functions and data types beyond those provided by the core language. For example, Starlark was originally developed for the Bazel build tool. Bazel uses Starlark as the notation both for its BUILD files (like Makefiles, these declare the executables, libraries, and tests in a directory) and for its macro language, through which Bazel is extended with custom logic to support new languages and compilers.
Design Principles
- Deterministic evaluation. Executing the same code twice will give the same results.
- Hermetic execution. Execution cannot access the file system, network, system clock. It is safe to execute untrusted code.
- Parallel evaluation. Modules can be loaded in parallel. To guarantee a thread-safe execution, shared data becomes immutable.
- Simplicity. We try to limit the number of concepts needed to understand the code. Users should be able to quickly read and write code, even if they are not experts. The language should avoid pitfalls as much as possible.
- Focus on tooling. We recognize that the source code will be read, analyzed, modified, by both humans and tools.
- Python-like. Python is a widely used language. Keeping the language similar to Python can reduce the learning curve and make the semantics more obvious to users.
Tour
The code provides an example of the syntax of Starlark:
# Define a number
number = 18
# Define a dictionary
people = {
"Alice": 22,
"Bob": 40,
"Charlie": 55,
"Dave": 14,
}
names = ", ".join(people.keys()) # Alice, Bob, Charlie, Dave
# Define a function
def greet(name):
"""Return a greeting."""
return "Hello {}!".format(name)
greeting = greet(names)
above30 = [name for name, age in people.items() if age >= 30]
print("{} people are above 30.".format(len(above30)))
def fizz_buzz(n):
"""Print Fizz Buzz numbers from 1 to n."""
for i in range(1, n + 1):
s = ""
if i % 3 == 0:
s += "Fizz"
if i % 5 == 0:
s += "Buzz"
print(s if s else i)
fizz_buzz(20)
If you've ever used Python, this should look very familiar. In fact, the code above is also a valid Python code. Still, this short example shows most of the language. Starlark is indeed a very small language.
For more information, see:
- Discussions for some design choices
- Why Starlark was created (previously named Skylark)
- The specification
- The mailing-list: starlark@googlegroups.com
Build API
The first use-case of the Starlark language is to describe builds: how to compile a C++ or a Scala library, how to build a project and its dependencies, how to run tests. Describing a build can be surprisingly complex, especially as a codebase mixes multiple languages and targets multiple platforms.
In the future, this repository will contain a complete description of the build API used in Bazel. The goal is to have a clear specification and precise semantics, in order to interoperate with other systems. Ideally, other tools will be able to understand the build API and take advantage of it.
Evolution
Read about the design process if you want to suggest improvements to the specification. Follow the mailing-list to discuss the evolution of Starlark.
Implementations, tools, and users
See the Starlark implementations, tools, and users page.
Top Related Projects
Skylark in Go: the Skylark configuration language, implemented in Go [MOVED to go.starlark.net]
HCL is the HashiCorp configuration language.
Maintainable configuration files
Common Expression Language -- specification and binary representation
A fast build system that encourages the creation of small, reusable modules over a variety of platforms and languages.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot