Repositories, workspaces, packages, and targets

Report an issue View source Nightly · 7.2 · 7.1 · 7.0 · 6.5 · 6.4

Bazel builds software from source code organized in directory trees called repositories. A defined set of repositories comprises the workspace. Source files in repositories are organized in a nested hierarchy of packages, where each package is a directory that contains a set of related source files and one BUILD file. The BUILD file specifies what software outputs can be built from the source.


Source files used in a Bazel build are organized in repositories (often shortened to repos). A repo is a directory tree with a boundary marker file at its root; such a boundary marker file could be MODULE.bazel, REPO.bazel, or in legacy contexts, WORKSPACE or WORKSPACE.bazel.

The repo in which the current Bazel command is being run is called the main repo. Other, (external) repos are defined by repo rules; see external dependencies overview for more information.


A workspace is the environment shared by all Bazel commands run from the same main repo. It encompasses the main repo and the set of all defined external repos.

Note that historically the concepts of "repository" and "workspace" have been conflated; the term "workspace" has often been used to refer to the main repository, and sometimes even used as a synonym of "repository".


The primary unit of code organization in a repository is the package. A package is a collection of related files and a specification of how they can be used to produce output artifacts.

A package is defined as a directory containing a BUILD file named either BUILD or BUILD.bazel. A package includes all files in its directory, plus all subdirectories beneath it, except those which themselves contain a BUILD file. From this definition, no file or directory may be a part of two different packages.

For example, in the following directory tree there are two packages, my/app, and the subpackage my/app/tests. Note that my/app/data is not a package, but a directory belonging to package my/app.



A package is a container of targets, which are defined in the package's BUILD file. Most targets are one of two principal kinds, files and rules.

Files are further divided into two kinds. Source files are usually written by the efforts of people, and checked in to the repository. Generated files, sometimes called derived files or output files, are not checked in, but are generated from source files.

The second kind of target is declared with a rule. Each rule instance specifies the relationship between a set of input and a set of output files. The inputs to a rule may be source files, but they also may be the outputs of other rules.

Whether the input to a rule is a source file or a generated file is in most cases immaterial; what matters is only the contents of that file. This fact makes it easy to replace a complex source file with a generated file produced by a rule, such as happens when the burden of manually maintaining a highly structured file becomes too tiresome, and someone writes a program to derive it. No change is required to the consumers of that file. Conversely, a generated file may easily be replaced by a source file with only local changes.

The inputs to a rule may also include other rules. The precise meaning of such relationships is often quite complex and language- or rule-dependent, but intuitively it is simple: a C++ library rule A might have another C++ library rule B for an input. The effect of this dependency is that B's header files are available to A during compilation, B's symbols are available to A during linking, and B's runtime data is available to A during execution.

An invariant of all rules is that the files generated by a rule always belong to the same package as the rule itself; it is not possible to generate files into another package. It is not uncommon for a rule's inputs to come from another package, though.

Package groups are sets of packages whose purpose is to limit accessibility of certain rules. Package groups are defined by the package_group function. They have three properties: the list of packages they contain, their name, and other package groups they include. The only allowed ways to refer to them are from the visibility attribute of rules or from the default_visibility attribute of the package function; they do not generate or consume files. For more information, refer to the package_group documentation.