0.3.2 Rules

After the file layout and declarative model from 0.3.1 Anatomy of a BUILD File, the next question is what those top-level calls actually are. java_library, cc_binary, and sh_test are rules: schemas for a kind of target. Calling one in a BUILD file instantiates a rule target with a label, attributes, and hidden implementation logic that Bazel later uses to produce artifacts and dependency information.1,2,3

What does each part of a rule call mean?
The call creates //app:server. Its parts define the rule kind, target name, and attribute values.
BUILD.bazel package //app
1 java_binary(
2 name = "server",
3 srcs = ["Main.java"], 4 deps = [":lib"],
5 )
The package plus the name yields the final label.
LABEL //app:server
RULE
Rule kind
kind + hidden logic
java_binary
TARGET
Target name
name + package form its label
//app:server
ATTRIBUTES
Attribute values
fields allowed by this rule kind
srcs, deps
A rule call creates one rule target.

Rule Is A Type, Target Is An Instance

A real example appears in app/BUILD.bazel:

java_binary(
    name = "server",
    srcs = ["Main.java"],
    deps = [":lib"],
)

In that snippet, java_binary is the rule. server is the target name. Together with the package path //app, that declaration becomes the label //app:server.1,2,4 A rule is not the same thing as a rule target, even though people sometimes use the words loosely.4

That distinction matters because labels from 0.2.1 Label Anatomy point at targets, not at rule types. A BUILD file is therefore mostly a list of instantiated rule types: each call creates one target that other targets can depend on later.2,4

What A Rule Contributes

A rule does two jobs. First, it defines the attribute schema available in the call: which fields exist, and what kind of information they accept. Second, it hides the build logic that turns those attribute values into outputs and metadata for downstream targets.1,3,4

For a BUILD-file author, that means you do not spell out compiler invocations or file-copy steps in the BUILD file. You fill in facts such as name, source files, and dependencies, and the rule implementation handles the mechanics.1,4 That is also why 0.3.3 Attributes & Semantic Roles deserves its own article: the meaning of srcs, deps, data, or rule-specific fields comes from the rule kind you are calling.

Rule Families Help You Read Intent

Most rules come in recognizable families. A common pattern spans *_library, *_binary, and *_test: libraries are separately compiled modules, binaries are executable programs, and tests are specialized executables for automated verification.2 When you see those names in a BUILD file, you can already make a good first guess about how the target is meant to be used.

That naming pattern also explains why a java_binary is something you may later run with 1.1.2 bazel run & Runfiles, while a java_library is usually something other targets depend on. The prefix often signals the language or ruleset: cc_* for C++, java_* for Java, and many others supplied by external rulesets rather than Bazel core itself.1,2,4 P.2.3 Core vs Rulesets explains the bigger split between the generic engine and language plugins. 0.3.5 Load Statements shows how rule symbols enter a BUILD file.

extra

Why Some Old BUILD Files Have Fewer load() Lines

The direction of modern Bazel is to make rule origins explicit and uniform: if a BUILD file uses a rule symbol from a ruleset, it should load that symbol near the top of the file. That makes the file's vocabulary visible before the target declarations begin, which is the main beginner-level habit to build before 0.3.5 Load Statements.

Older Bazel versions have a historical quirk: some language rules were available without an explicit load() because they shipped through Bazel's built-in surface. Bazel 8 started the transition with automatic loading to give projects time to migrate, and Bazel 9 disables that autoloading so rules come from their own repositories explicitly.5,6 If you read an older example that calls cc_library or java_library without a matching load(), treat that as compatibility history, not the pattern to copy into new material.

Not Every Target Is A Rule Target

Not every label in Bazel names a rule target. The official terminology separates rule targets from file targets, and also treats package_group as its own target kind used mainly for visibility control.3,4 //app:server is a rule target, //app:Main.java is a file target, and a package_group target exists to be referenced from visibility settings rather than to compile code.3

The distinction prevents a common beginner mistake when reading BUILD files: assuming that every target is "some rule invocation." Rules are the most important target kind in everyday BUILD-file reading, but they are still just one category inside the broader target model.3,4

key takeaway

A rule is the type. A rule target is the instance created by calling that type in a BUILD file. When you open an unfamiliar package, first identify the rule families in use, then read each call as "one target of this kind with these attributes." The next step is 0.3.3 Attributes & Semantic Roles, where those fields get their semantic roles. Defining brand-new rule types waits until 4.2 Custom Rules, Providers & Actions.

Check your understanding · 2 questions

1.Match each rule family to its typical role in a Bazel build:

Drag each answer onto the matching prompt, or click an answer and then click a prompt

Answers
*_library
*_binary
*_test

2.True or false: rules, targets, and target kinds.

Choose True or False for each sentence

rule and rule target are not the same thing. Calling java_library creates a rule target.
Labels in BUILD files and on the command line point at targets, not at rule types.
The same rule can be called many times to create different targets, as long as each target has its own name.
rule target is the type. rule is one use of that type in a BUILD file.
0 of 2 answered

Footnotes

  1. Bazel Training 101 (Part 9): Packages, Rules, Targets, and Labels — rule as schema and black box, constructor-like rule calls, naming families, and common BUILD-file attributes 1 2 3 4 5

  2. BUILD files — rule calls creating targets, common *_library / *_binary / *_test families, and BUILD-file rule semantics 1 2 3 4 5

  3. Repositories, workspaces, packages, and targets — rule instances as input/output relationships, and the distinction between rule, file, and package-group targets 1 2 3 4 5

  4. Bazel Glossary — precise terminology for rule vs rule target, target kinds, native rules, and attribute schema 1 2 3 4 5 6 7 8

  5. Bazel 8.0 LTS Release Blog Post--incompatible_autoload_externally, modularized rulesets, and the migration toward explicit load statements before Bazel 9

  6. BazelCon 2025 Day 1: State of the Union — Starlarkification status, rule sets in their own repositories, and Bazel 9 disabling autoload