> ## Documentation Index
> Fetch the complete documentation index at: https://site.aspect.build/llms.txt
> Use this file to discover all available pages before exploring further.

# Packages, Rules, Targets, and Labels

> Learn the core Bazel vocabulary of packages, rules, targets, and labels, including how BUILD files define package boundaries and how glob and exports work.

Bazel has its own vocabulary for describing code structure. This guide explains the four core concepts you'll use every day: packages, rules, targets, and labels.

## Packages

Bazel uses files named `BUILD` (or `BUILD.bazel`) to describe the source files which may be built or tested. Any directory containing a `BUILD` file is called a “package” in Bazel. This includes subdirectories unless they have their own `BUILD` file.

```
repo/             # This is the "//" package
├── BUILD.bazel
├── ...
├── animations    # Here is the "//animations" package
│   ├── BUILD
│   ├── browser   # Here is "//animations/browser"
│   │   ├── BUILD
│   │   └── ...
|   |   ...
│   ├── src
│   │   └── index.ts  # No BUILD here, so still the "animations" package
│   ├── test
│   │   ├── BUILD
│   │   └── ...

```

### Package encapsulation

Bazel packages are isolated units with well-defined boundaries:

* [`glob`](https://bazel.build/reference/be/functions#glob) stays within the package. It is a function wildcard patterns for filenames such as `**/*.txt`.
* Source files are “owned” by their package and aren't visible outside, unless exposed with `exports_files`.
* Output files are always written to the `bazel-out` folder within the same package.

## Rules

Bazel [defines a rule](https://bazel.build/reference/glossary#rule) as a schema for defining [rule targets](https://bazel.build/reference/glossary#rule-target) in a `BUILD` file, such as `sh_library`.
From the perspective of a `BUILD` file author, a rule consists of:

* A set of [attributes](https://bazel.build/reference/glossary#attributes) and,
* A black box logic which tells the rule target how to produce output  [artifacts](https://bazel.build/reference/glossary#artifact) and pass information to other rule targets.

Rules are provided by “rulesets”, which are Bazel plugins loaded from the `MODULE.bazel` file, such as `rules_shell`. You may think of a rule as a factory function or a constructor. Call it from `BUILD` to describe your sources. The result is a type of target called a “rule target”.

### Rule Naming Convention

A rule is generally designed to be used with a particular `bazel` command, making it buildable, runnable, and/or testable.

A naming convention typically hints which one it is:

| A rule named | is invoked with | to                |
| ------------ | --------------- | ----------------- |
| `foo`        | `bazel build`   | produce outputs   |
| `foo_binary` | `bazel run`     | have side-effects |
| `foo_test`   | `bazel test`    | assert exit `0`   |

<Note> Unlike other build systems, most rules do not allow you to give procedural logic for what to do, that’s the job of the rule implementation logic. Rules only describe the source files and their dependencies. </Note>

## Rule example

```python theme={null}
sh_binary(
    name = "run_me",
    srcs = ["my_script.bash"],
    env = {"ENV": "dev"},
    data = ["my.json"],
    deps = ["//lib:bash_helpers"],
)
```

The arguments to this `sh_binary` rule are called "attributes".
Common attributes across most rules include:

* `name` is always required. Use this in a label to refer to the target
* `srcs` typically means files in the source tree
* `deps` typically means other rule targets which are needed at build time
* `data` is like `deps` but is only needed at runtime

Other attributes are particular to the rule implementation.

* `env` is an attribute present on all executable targets, providing environment variables when the target is executed with `bazel run`

## Targets

Not all targets are created from rules, there are a few other [types of target](https://bazel.build/reference/glossary#target):

1. Source files: refer to an individual file in the source tree.
2. Build output files (so long as they are pre-declared).
3. Package groups, which are useful with Bazel’s visibility feature.

### Target Patterns

On the command-line, you may want to refer to groups of targets. There are some special syntax:

* `:all` or `:*` means “all targets in this package”
* `...` means “all targets recursively in this package and subpackages”
* `//...` means “all targets in this repository”

## Labels

[Labels](https://bazel.build/reference/glossary#label) are the way to reference a target from the command-line or in a `BUILD` file.
Think of labels like a URL for a target.

### Label syntax

```
          ┌ package name ┐
          v              v
@my_repo//my_library/utils:draw_circle
   ^                           ^
   |                           └- target
   |
   └- "apparent" repository name (optional)

```

<Note>
  Sometimes you might see a label starting with a double-`@` sign.
  This is a “canonical” repository name, and you should not need to use it.
  This is a way to bypass the visibility restriction, but the name of the resulting repositories is brittle and hard to predict.
</Note>

### Label shorthand

If the working directory is in the same repository, `//my_library/util:draw_circle`

* `//` means the root of that repository.
* On the command line, labels can be relative to the working directory
* Each package has a default label, named after the package

You can usually use this shorthand to save typing.
For example you could just `cd backend; bazel run devserver` rather than
`bazel run //backend/devserver:devserver`.

Every package should have a thoughtfully chosen default target, to save typing and make an ergonomic experience for developers interacting with Bazel in your project.
You can use `alias` to introduce an indirection, for example if you'd like users to be able to
`bazel run backend` from the repository root, then you add an `alias`:

```python theme={null}
alias(
    name = "backend",   # the default target for the backend package
    actual = "//backend/devserver",
)
```

<Note>
  You can get a reminder of the syntax with `bazel help target-syntax`
</Note>
