tomato·bazeldocs v0 · latest
Docs/Reference/Modules/rules_eslint

rules_eslint

Hermetic eslint runner — lint a workspace's @npm eslint binary under Bazel

Latest0.1.0
Versions1
CategoryBazel rules
MaintainersMatt Marshall
Registryhttps://registry.tbzl.dev/modules/rules_eslint/
Sourcegithub.com/tomato-bazel/rules_eslint
MODULE.bazelstarlark
bazel_dep(name = "rules_eslint", version = "0.1.0")

View source & releases on GitHub ↗

Hermetic eslint runner — lint a workspace’s @npm eslint binary under Bazel.

eslint is a Node tool whose binary + plugin/config closure live in your pnpm-lock.yaml. So rules_eslint does not fetch eslint. It gives you a small eslint_test macro that runs your own aspect_rules_js-linked eslint binary over a set of sources as a Bazel test — the same “consumer supplies the binary” shape as rules_storybook and rules_nextjs.

Status: v0.1.0

  • eslint_test(name, srcs, eslint_bin, config, ...) — a lint-tagged sh_test that runs eslint_bin --config <config> <srcs>.

Install

.bazelrc:

common --registry=https://registry.fastverk.com/
common --registry=https://bcr.bazel.build/

MODULE.bazel:

bazel_dep(name = "rules_eslint", version = "0.1.0")

Use

You already have eslint in your pnpm-lock.yaml and an @npm repo from aspect_rules_js’s npm_translate_lock. Materialize the eslint binary with the bin factory, then point eslint_test at it:

load("@npm//:eslint/package_json.bzl", eslint_bin = "bin")
load("@rules_eslint//eslint:defs.bzl", "eslint_test")

eslint_bin.eslint_binary(name = "eslint")

eslint_test(
    name = "lint",
    srcs = glob(["**/*.ts", "**/*.tsx"]),
    eslint_bin = ":eslint",
    config = "//:eslint.config.mjs",
)

Run one target, or fan out across the repo:

bazel test //:lint
bazel test //... --test_tag_filters=lint

Because eslint, its plugins, and the flat config all come from your own @npm closure + sources, the test is hermetic and reproducible — no reliance on a node_modules/.bin/eslint on the CI runner.

See examples/smoke for a complete, self-contained workspace.

Usage#

Real usage, taken from the module’s examples/.

examples/smoke/BUILD.bazel

load("@rules_eslint//eslint:defs.bzl", "eslint_test")
load("@smoke_npm//:defs.bzl", "npm_link_all_packages")
load("@smoke_npm//examples/smoke:eslint/package_json.bzl", eslint_bin = "bin")

package(default_visibility = ["//visibility:public"])

npm_link_all_packages(name = "node_modules")

exports_files(["pnpm-lock.yaml"])

# The consumer's own @npm eslint binary — what a real workspace passes to
# `eslint_test`. Here it comes from the pinned smoke npm workspace.
eslint_bin.eslint_binary(name = "eslint_cli")

# Release gate: a real `eslint_test` over a clean source, exercising the
# macro (binary + config + srcs → runfiles → eslint) end-to-end. Runs in
# `bazel test //...` on every CI OS.
eslint_test(
    name = "smoke_test",
    srcs = ["clean.js"],
    config = "eslint.config.mjs",
    eslint_bin = ":eslint_cli",
)

Conformance#

No gate findings. 17 contested atoms. See how gating works or the full report.

Contested atoms

Third-party modules where this module resolves a different version than others do. Not a violation of anything this module did — it is the actionable form of a registry-level convergence finding, and the sentence a maintainer can act on.

AtomResolved hereElsewhere
apple_support 1.24.2 2.2.0 ×1
aspect_bazel_lib 2.22.5 2.8.1 ×1
aspect_rules_js 3.1.2 2.1.3 ×1
bazel_lib 3.2.2 3.0.0 ×12
bazel_skylib 1.8.2 1.9.0 ×2
gawk 5.3.2.bcr.3 5.3.2.bcr.1 ×12
jq.bzl 0.4.0 0.1.0 ×12
nlohmann_json 3.6.1 3.12.0.bcr.1 ×1
package_metadata 0.0.2 0.0.5 ×3
protobuf 33.4 34.0.bcr.1 ×2
rules_jvm_external 6.7 6.8 ×4
rules_nodejs 6.7.4 6.3.0 ×16.7.3 ×1
rules_python 1.7.0 2.0.1 ×1
rules_swift 3.1.2 3.6.1 ×1
tar.bzl 0.10.4 0.5.1 ×110.6.0 ×1
upb 0.0.0-20220923-a547704 0.0.0-20230516-61a97ef ×1
yq.bzl 0.3.4 0.1.1 ×12

Dependencies#

rules_eslint in the registry graph — what it depends on (left) and what depends on it (right).

Depends on

platforms1.0.0bazel_skylib1.8.2rules_shell0.6.1stardoc0.7.2devaspect_rules_js3.1.2devrules_nodejs6.7.4dev

Versions#

1 published version, newest first. Each resolves to an immutable, integrity-checked archive.

VersionIntegrity (sha256)Source archive
0.1.0 latest IQcBOfAWvyCdPZ71… tag archive ↗

Changelog#

All notable changes to rules_eslint. The format is loosely Keep a Changelog — version headers mirror the published bazel-registry entries.

0.1.0

  • eslint_test(name, srcs, eslint_bin, config, tags = None, **kwargs) in //eslint:defs.bzl — a lint-tagged sh_test that runs a consumer-supplied @npm eslint binary (eslint_bin) over srcs against a flat config. eslint + plugins + config all come from the consumer’s own pnpm-lock.yaml/@npm closure; the ruleset fetches nothing. The launcher (//eslint/private:run_eslint.sh) resolves the binary + config via the bazel runfiles library and forwards the sources to eslint --config <config>.
  • //examples/smoke — a self-contained workspace pinning a real @npm eslint, used as the release gate.

0.0.1 — scaffold

  • Initial scaffold via rels scaffold. No public API yet.

← All modules