4.3.6 Starlark REPL / Playground

extra

Starlark REPLs and playgrounds are scratchpads for language questions. They are useful when the question is "what does this Starlark expression or helper function do?" They are not a miniature Bazel server, a macro-expansion viewer, or a way to inspect configured targets.

The boundary matters because Starlark has Python-inspired syntax, but Bazel-specific semantics and file contexts. The official language page points out that Starlark behavior can differ from Python, that .bzl files and BUILD files have different roles, and that BUILD files have extra syntactic restrictions such as no function declarations and no *args or **kwargs arguments.1 A REPL can help you explore the language. It cannot reproduce every context where Bazel evaluates that language.

What A REPL Is Good For

Use a REPL or playground for small, pure Starlark experiments:

def unique(values):
    seen = {}
    result = []
    for value in values:
        if value not in seen:
            seen[value] = True
            result.append(value)
    return result

unique(["fast", "dbg", "fast"])

That kind of snippet is a good fit because it does not depend on a package, a label, a configured target, a ctx object, or Bazel's native rule APIs. You are checking language shape: list and dict behavior, function control flow, equality, ordering, string representation, or whether a Python habit is also legal Starlark.

The official language reference is especially useful for deciding what to test. It documents mutability and freezing: lists and dicts are mutable only for objects created in the current context, and values become immutable after their context finishes.2 It also lists Python differences such as no recursion, no while, no exceptions, no import, and BUILD-file restrictions.3 Those are the kinds of rules a scratchpad can make concrete before you put the code inside a rule or macro.

What It Cannot Prove

The starlark-go map is a useful portability check because upstream explicitly documents dialect differences from Bazel's Java implementation. Its example_test.go is executable documentation for embedding APIs such as Thread.Load. Those are Go host APIs, not names available in Bazel BUILD or .bzl evaluation.

A REPL does not know what Bazel will load for a package. It does not expand macros, resolve labels through a caller's BUILD file, apply select(), construct ctx, return providers, or declare actions. If the code mentions native.package_name(), Label(), ctx.actions, DefaultInfo, a toolchain, or a provider from another rule, the interesting behavior is not just Starlark syntax anymore. It is Bazel evaluation.

For those questions, switch back to the section's Bazel-aware tools. Use 4.3.2 Macro Expansion Inspection when you need to see the rules a macro emitted. Use 4.3.1 Print Debugging when you need a value from loading or analysis. Use 4.3.5 Starlark Debugger when control flow is too complex for snapshots and you need breakpoints.

That is also why exact launch commands should be treated as environment-specific. A Starlark REPL sits alongside the VS Code Starlark debugger as a tool for cases where macro code itself fails.4 In practice, do not build your ruleset workflow around a universal bazel starlark command. Bazel's stable proof loop for repository behavior is still build, query, cquery, aquery, targeted tests, and the debugger when you need it.

A Useful Workflow

The best REPL workflow is short:

  1. Extract the pure helper you want to reason about.
  2. Remove Bazel-only objects from the experiment.
  3. Test a few concrete inputs.
  4. Move the helper back into .bzl code.
  5. Prove the Bazel-facing behavior with the right tool.

For example, a helper that normalizes a list of mode strings can be explored interactively. The rule implementation that reads ctx.attr.mode, chooses outputs, and registers an action cannot. After the helper returns to the rule, use print() for a temporary analysis-time value, bazel query --output=build for macro output, or the query family from 5.2 Query when the question is about the target graph.

Keep The Tool In Its Lane

REPLs are most valuable because they are small. They remove the package graph, configuration, action graph, and remote execution from the feedback loop. That makes them fast and clear for language semantics, but it also means they are deliberately blind to the parts of Bazel that make a rule or macro useful.

Treat the REPL as an extra tool after formatting, editor feedback, print(), query output, and the debugger. If a snippet only uses Starlark values, try it interactively. If the snippet needs Bazel to answer, let Bazel answer.

key takeaway

A Starlark REPL or playground is for pure language experiments. It helps you test syntax, functions, and small data transformations before putting them into .bzl files.

It does not validate macro expansion, label resolution, configured targets, providers, toolchains, or actions. Use Bazel-aware tools for those.

Check your understanding · 3 questions

1.Which question is a good fit for a Starlark REPL or playground?

Select one answer

2.Which topics should send you back to Bazel-aware debugging tools instead of a standalone REPL?

Select all that apply

3.True or false: limits of using a Starlark REPL or playground.

Choose True or False for each sentence

bazel starlark should be treated as a portable, cross-version workflow dependency.
A REPL is a good place to confirm that a Starlark expression behaves differently than its closest Python equivalent.
A passing REPL session is sufficient evidence that a load() chain works inside a real BUILD package.
If a question depends on select(), ctx, providers, or toolchain resolution, switch back to Bazel-aware tools instead of a REPL.
0 of 3 answered

Footnotes

  1. Starlark Language — syntax overview, BUILD versus .bzl file roles, and BUILD-file restrictions.

  2. Starlark Language — mutability model and freezing after an evaluation context finishes.

  3. Starlark Language — differences from Python, including unsupported language features.

  4. Sponsored Session: Enough Bazel to Be Dangerous: A Debugging Cookbook - Instructor: Alejandro Gomez — REPL and Starlark debugger as tools for macro-code failures.