Bazel Integration
The Bazel integration requires Pyrefly 1.2 or later and uses the
pyrefly bazel-check subcommand with the companion ruleset
rules_pyrefly (available via the
Bazel Central Registry; check
there for the latest version).
Instead of writing custom build logic to collect sources, dependencies, import
paths, and generated files, you can apply Pyrefly as a Bazel
aspect over existing py_library,
py_binary, and py_test targets.
pyrefly bazel-check and the rules_pyrefly Starlark API are under active
development and may still see breaking changes in minor rules_pyrefly releases
before they stabilize. Please try the integration and report any problems in the
appropriate repository. See
rules_pyrefly releases and
pyrefly/private/versions.bzl
for the currently supported Pyrefly version(s).
When to use it
- Your Python code is already built with
rules_pythonand you wantbazel buildto also type-check it. - You want one pinned Pyrefly version per repository, resolved hermetically through a Bzlmod toolchain, with no per-
BUILDfile boilerplate.
If you do not use Bazel, use pyrefly check as before. The Bazel integration does not read pyrefly.toml; checking policy is configured on the aspect.
Setup
1. Add the dependency and register a toolchain
This guide assumes your root MODULE.bazel already declares rules_python. Keep
that existing bazel_dep unchanged; adding a second declaration causes an error.
Choose each version independently:
RULES_PYREFLY_VERSION: the latest compatiblerules_pyreflyrelease.PYREFLY_VERSION: a version listed inpyrefly/private/versions.bzl.
Replace the uppercase placeholders below in your root MODULE.bazel:
bazel_dep(name = "rules_pyrefly", version = "RULES_PYREFLY_VERSION")
pyrefly = use_extension("@rules_pyrefly//pyrefly:extensions.bzl", "pyrefly")
pyrefly.toolchain(version = "PYREFLY_VERSION")
use_repo(pyrefly, "pyrefly_toolchains")
register_toolchains("@pyrefly_toolchains//:all")
For forks, mirrors, or prereleases that are not in the checked-in release
metadata, pyrefly.toolchain also accepts base_url + sha256 — see the
rules_pyrefly README
for that form.
2. Define an aspect
The aspect can live in any .bzl file in a Bazel package. This example creates an
empty tools/BUILD.bazel so Bazel recognizes //tools as a package, then exports
the aspect from tools/aspects.bzl:
# tools/aspects.bzl
load("@rules_pyrefly//pyrefly:pyrefly.bzl", "pyrefly")
pyrefly_aspect = pyrefly()
If you choose another location, update the --aspects label in the next step to
match.
With no arguments the aspect infers the Python version from the
rules_python toolchain and the platform from Bazel platform constraints. For
the full set of overrides, see the rules_pyrefly README.
3. Wire it in .bazelrc
# .bazelrc
build:pyrefly --aspects=//tools:aspects.bzl%pyrefly_aspect
build:pyrefly --output_groups=pyrefly
--output_groups=pyrefly is a type-check-only build. Use
--output_groups=+pyrefly only when you also want the normal target outputs.
4. Run
# one package
bazel build --config=pyrefly //path/to/package:target
# whole repo (with --keep_going to collect all findings in one pass)
bazel build --config=pyrefly --keep_going //...
Diagnostics are printed to Bazel's stderr, and error-severity findings fail the
action. The rules_pyrefly aspect configuration
controls the minimum severity; at its default error threshold, lower-severity
findings are omitted from both stderr and the per-target JSON. The minimum-severity
filter does not remove reveal_type() output. The JSON diagnostics are available in
the pyrefly output group, and the generated input JSON is available in the
debug-only pyrefly_input output group.
How it works
Each eligible Python target gets one pyrefly bazel-check action that checks
the target's own sources (from PyInfo) with its dependencies available for
import resolution. Implementation details, including target selection, check roots,
search-path facts, path overlays for generated files, output groups, and the
JSON contract, live in rules_pyrefly docs/integration.md and the
Pyrefly-side parser in pyrefly/lib/commands/bazel_check.rs.
For design tradeoffs and rationales, see
rules_pyrefly docs/design.md and
docs/users.md.