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
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
When deps() gets noisy, rerun it with --noimplicit_deps. That flag helps when implicit tool or rule dependencies bury the relationships you declared explicitly in BUILD files.1,4,5
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
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
2.Which statements about this first bazel query workflow are true?
Choose True or False for each sentence
Footnotes
-
Query quickstart — beginner framing of
bazel query, workspace exploration,deps(), and--noimplicit_deps↩1 ↩2 ↩3 ↩4 ↩5 ↩6 -
Deep dive into Bazel queries: from basics to advanced use cases — target-pattern mindset, practical
queryusage, and the boundary betweenquery,cquery, andaquery↩1 ↩2 ↩3 ↩4 ↩5 -
A guide to Bazel query —
bazel query //...as workspace inventory and//pkg/...as a narrower slice of the repo ↩1 ↩2 ↩3 ↩4 -
Query guide —
deps()semantics, flat query output, and the role of--noimplicit_deps↩1 ↩2 ↩3 ↩4 -
Everything You Need to Know about Bazel Query — practical explanation of
deps()closures and implicit-dependency noise ↩1 ↩2 ↩3