1.1.8 Basic Query

bazel query is a read-only graph inspector. The first useful split is between scope selectors and graph walks: //... or //app/... select rule targets by where they live in the current repository, while deps(//app:runner) follows declared edges from one starting target and can leave that directory slice entirely.1,2,3 It uses the same label and target-pattern language as 1.1.1 Commands and 0.2.3 Target Patterns, but instead of producing artifacts it prints graph information you can inspect first.1,2

Target patterns select by location. deps() follows declared dependencies.
The arrows trace the rule chain from //app:runner: //app:runner//app/data:repo//config:app_config//lib:core@rules_shell//.... Green outlines mark the full result, including files.
bazel query //...
5 rule targets in the main repo
bazel query //app/...
rule targets in //app and its subpackages
bazel query 'deps(//app:runner)'
green outline marks the nodes in the real query result
main repo
location selected by //app/...
//app
//app:runner
//app/data
//app/data:repo
//service
//service:menu
Found by //..., but it is not a dependency of //app:runner.
//config
//config:app_config
//config:app.json
//lib
//lib:core
//lib:core.txt
Blue rule pills are found by //.... The gold boundary shows the smaller set found by the location pattern //app/....
external repo
@rules_shell
@rules_shell//shell/runfiles:runfiles.bash
Included by deps() because the start target depends on it. It is outside the main repo, so //... never selects it.
//... and //app/... find rule targets by location in the main repo. deps(//app:runner) starts from one target and follows its dependencies, including files and external repositories.

Start with scope: //... and //app/...

bazel query //... is the blunt first scan: expand the repo-wide target pattern and print the rule targets it matches in the current repository.1,2,3 In the basic-query snippet, that gives:

//app:runner
//app/data:repo
//config:app_config
//lib:core
//service:menu

Narrowing the target pattern keeps the same idea but changes the slice. bazel query //app/... asks for the rule targets in //app and its subpackages, not for the dependencies of //app:runner.2,3

//app:runner
//app/data:repo

Target patterns answer "what targets live here?" by slicing the current repository by package location.

Use deps() when the question is reachability

deps(x) asks for the transitive closure of everything reachable from target x, including x itself.1,4,5 In the same snippet, bazel query 'deps(//app:runner)' returns:

//app:runner
//app/data:repo
//config:app.json
//config:app_config
//lib:core
//lib:core.txt
@rules_shell//shell/runfiles:runfiles.bash

This is doing a different job from //app/.... In this snippet, the rule-target chain is //app:runner -> //app/data:repo -> //config:app_config -> //lib:core, and the reachable set also includes //config:app.json, //lib:core.txt, and one external-repository label. deps() follows edges. It does not stay inside the directory subtree you started from.4,5

The output is a flat list, not a rendered tree. It contains the reachable graph nodes Bazel traversed, even when your mental model of the closure is a chain or fan-out.1,4

Preview The Graph Before Going Deeper

For a first pass, stop at navigation. Use bazel query //... or bazel query //pkg/... to inventory a slice of the repo, and use deps() when you want the reachable closure from one starting target. Questions such as "who depends on this?" (2.1.6 Reverse Dependencies & Change Impact), "what path introduces that dependency?", or "what does the configured graph really look like?" need more specialized queries. 2.1.5 Inspecting the Graph — Query Preview reconnects this habit to the DAG model, and 5.2 Query covers rdeps(), somepath(), cquery, and aquery.2,3

key takeaway

Target patterns such as //... and //app/... slice the current repository by package location. deps(//pkg:target) answers a different question: what graph nodes are reachable from this target, even if that walk reaches files or external repositories. That distinction is enough to navigate an unfamiliar Bazel repo without building it.

Check your understanding · 2 questions

1.Match each query expression to the question it answers:

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

Answers
//app/...
deps(//app:runner)

2.Which statements about this first bazel query workflow are true?

Choose True or False for each sentence

bazel query inspects graph information without compiling the selected targets.
deps() always stays inside the package subtree of its starting label.
--noimplicit_deps can reduce rule-injected dependency noise.
0 of 2 answered

Footnotes

  1. Query quickstart — beginner framing of bazel query, workspace exploration, deps(), and --noimplicit_deps 1 2 3 4 5 6

  2. Deep dive into Bazel queries: from basics to advanced use cases — target-pattern mindset, practical query usage, and the boundary between query, cquery, and aquery 1 2 3 4 5

  3. A guide to Bazel querybazel query //... as workspace inventory and //pkg/... as a narrower slice of the repo 1 2 3 4

  4. Query guidedeps() semantics, flat query output, and the role of --noimplicit_deps 1 2 3 4

  5. Everything You Need to Know about Bazel Query — practical explanation of deps() closures and implicit-dependency noise 1 2 3