Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

rules_bun

API reference, generated from the module’s .bzl docstrings (stardoc).


User-facing rules for rules_bun.

Four pieces:

  • bun_test — runs bun test as a hermetic Bazel test action with explicit srcs + deps. Returns a BunTestInfo provider wrapping the test result file (for downstream consumers; the main consumer is the test framework, which only cares about exit codes).

  • bun_run — sh_binary macro: bazel run //path:NAME invokes bun run <script> against the live workspace source. Intentionally non-hermetic (escapes the runfiles sandbox) for the dev loop. Counterpart to bun_test’s hermetic execution.

  • bun_bundle — bundle a JS/TS entry point into one self-contained file with bun build. Returns BunBundleInfo.

  • bun_compile — compile a JS/TS entry point into a standalone native executable with bun build --compile (Bun runtime + bundled JS). Returns BunBinaryInfo and is bazel run-nable.

All resolve the Bun binary via @rules_bun//bun:toolchain_type (set up by register_toolchains("@bun//:bun_toolchain_def") in your MODULE.bazel).

bun_bundle / bun_compile have two ways to provision node_modules:

  • Bun-native (recommended; no aspect_rules_js, no pnpm-lock): pass a node_modules label (a @<name>//:node_modules from a bun_deps.install tag — see extensions.bzl) plus srcs (the entry

    • local modules). bun build runs directly via the toolchain Bun; a small shell driver stages the entry into a real tree and symlinks the closure so Bun resolves the import graph natively.
  • Legacy aspect_rules_js: pass a driver js_binary whose entry point is @rules_bun//bun:bun-build-driver and whose data stages the build entry plus its full linked node_modules closure; aspect materializes that closure into the action runfiles.

driver and node_modules are mutually exclusive — set exactly one. bun_test likewise takes an optional node_modules for dep resolution.

bun_bundle

load("@rules_bun//bun:defs.bzl", "bun_bundle")

bun_bundle(name, srcs, out, driver, entry, external, format, node_modules, target)

Bundle a JS/TS entry into one file via the hermetic Bun toolchain. Either Bun-native (node_modules from bun_deps.install, no aspect_rules_js) or the legacy aspect driver js_binary path.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
srcsBun-native path. The entry file + any local modules it imports, declared as action inputs. Ignored on the legacy driver path (that stages sources via the js_binary’s data).List of labelsoptional[]
outThe single bundled output file (conventionally *.mjs).Labelrequired
driverLEGACY aspect_rules_js path. A js_binary whose entry point is @rules_bun//bun:bun-build-driver and whose data stages the bundle entry + its full linked node_modules closure. Mutually exclusive with node_modules; set exactly one.LabeloptionalNone
entryPath of the entry point relative to the workspace root (e.g. packages/aion-cli/index.js). On the native path this is the execroot-relative path; on the legacy path it is relative to the driver’s _main runfiles root (same string in practice).Stringrequired
externalModule names to exclude from the bundle (passed as --external <name>, repeatable). Use for native addons and runtime requires that must stay external, e.g. pg-native, @aws-sdk/*, encoding, source-map-support.List of stringsoptional[]
formatBun --format. Defaults to esm so import.meta in deps stays valid under Node.Stringoptional"esm"
node_modulesBun-native path. A node_modules closure (typically @<name>//:node_modules from a bun_deps.install tag). When set, bun build runs directly via the toolchain Bun (no js_binary driver, no aspect_rules_js): the closure is symlinked to the execroot root so Bun resolves the import graph by walking up from entry. Mutually exclusive with driver. Pair with srcs (the entry + local modules).LabeloptionalNone
targetBun --target: the intended execution environment for the bundle. Defaults to node.Stringoptional"node"

bun_compile

load("@rules_bun//bun:defs.bzl", "bun_compile")

bun_compile(name, srcs, out, driver, entry, external, node_modules, target)

Compile a JS/TS entry into a standalone native executable (Bun runtime + bundled JS) via bun build --compile. Either Bun-native (node_modules) or the legacy aspect driver path.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
srcsBun-native path. The entry file + any local modules it imports, declared as action inputs. Ignored on the legacy driver path.List of labelsoptional[]
outThe standalone executable output. On --target bun-windows-* give it a .exe suffix.Labelrequired
driverLEGACY aspect_rules_js path. A js_binary whose entry point is @rules_bun//bun:bun-build-driver and whose data stages the build entry + its full linked node_modules closure. Mutually exclusive with node_modules; set exactly one.LabeloptionalNone
entryPath of the entry point relative to the workspace root (e.g. apps/studio-cli/index.js).Stringrequired
externalModule names to keep external (--external <name>, repeatable). NOTE: native .node addons are NOT embedded by --compile — list them here and provide the .node files at runtime alongside the produced binary.List of stringsoptional[]
node_modulesBun-native path. A node_modules closure (typically @<name>//:node_modules from a bun_deps.install tag). When set, bun build --compile runs directly via the toolchain Bun (no js_binary driver, no aspect_rules_js). Mutually exclusive with driver. Pair with srcs.LabeloptionalNone
targetBun compile target triple. Empty (the default) compiles for the host platform. Cross-compile values: bun-linux-x64, bun-linux-x64-modern, bun-linux-x64-baseline, bun-linux-arm64, bun-darwin-x64, bun-darwin-arm64, bun-windows-x64, and the *-musl libc variants (e.g. bun-linux-x64-musl). A future enhancement could derive this from the Bazel --platforms via a transition; for v1 pass the string.Stringoptional""

bun_test

load("@rules_bun//bun:defs.bzl", "bun_test")

bun_test(name, srcs, data, node_modules)

Run bun test over the listed source files as a Bazel test target.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
srcsTest files (typically *.test.ts, *.test.js). Each is passed to bun test explicitly so Bazel tracks them as inputs.List of labelsrequired
dataAdditional runtime inputs (fixtures, bunfig.toml, etc.).List of labelsoptional[]
node_modulesOptional node_modules closure (typically @<name>//:node_modules from a bun_deps.install tag). Staged at the workspace runfiles root as node_modules/ so bun test resolves dependency imports without bun install. The Bun-native replacement for aspect_rules_js’s npm_link_all_packages.LabeloptionalNone

BunBinaryInfo

load("@rules_bun//bun:defs.bzl", "BunBinaryInfo")

BunBinaryInfo(binary, target)

A standalone native executable produced by bun build --compile.

FIELDS

NameDescription
binaryFile: the standalone executable.
targetstring: the Bun compile target triple (empty = host).

BunBundleInfo

load("@rules_bun//bun:defs.bzl", "BunBundleInfo")

BunBundleInfo(bundle, format)

A single-file bundle produced by bun build.

FIELDS

NameDescription
bundleFile: the bundled output.
formatstring: the Bun output format (esm/cjs/iife).

BunTestInfo

load("@rules_bun//bun:defs.bzl", "BunTestInfo")

BunTestInfo(result)

Result metadata for a bun test run.

FIELDS

NameDescription
resultFile: the captured test output (stdout + stderr concatenated).

bun_run

load("@rules_bun//bun:defs.bzl", "bun_run")

bun_run(name, script, args, **kwargs)

Invoke bun run <script> against the live workspace source.

Escapes the runfiles sandbox via BUILD_WORKSPACE_DIRECTORY so Bun resolves modules + reads files from the user’s actual source tree. Intentionally NOT hermetic — that’s bun_test’s job.

PARAMETERS

NameDescriptionDefault Value
nametarget name.none
scriptpackage-relative path to the Bun script entry point.none
argsextra args passed to bun run after the script name.None
kwargsforwarded to the underlying sh_binary.none

Module extensions for rules_bun.

Two extensions:

  • bun — auto-fetches a prebuilt Bun binary for the host platform. Versions are sha256-pinned in private/known_versions.bzl. Consumers can override via the toolchain tag class.

    bun = use_extension("@rules_bun//bun:extensions.bzl", "bun")
    use_repo(bun, "bun")
    register_toolchains("@bun//:bun_toolchain_def")
    

    Pin a specific version:

    bun.toolchain(version = "1.3.14")
    
  • bun_deps — Bun-native node_modules staging. Each install tag produces a repo @<name> whose :node_modules filegroup is a bun install --frozen-lockfile-ed tree. The pure-Bun replacement for aspect_rules_js’s npm_translate_lock + npm_link_all_packages (no pnpm-lock, no aspect_rules_js):

    bun_deps = use_extension("@rules_bun//bun:extensions.bzl", "bun_deps")
    bun_deps.install(
        name = "npm",
        package_json = "//:package.json",
        lock = "//:bun.lock",
    )
    use_repo(bun_deps, "npm")
    

    then bun_test(node_modules = "@npm//:node_modules", ...) and bun_bundle(node_modules = "@npm//:node_modules", ...).

The actual release fetching is delegated to @rules_github//github:repositories.bzl%github_binary_repository so that the URL-shape + sha-pinning logic stays consistent across all our rules_* repos.

bun

bun = use_extension("@rules_bun//bun:extensions.bzl", "bun")
bun.toolchain(version)

Sets up @bun as a Bazel-fetched prebuilt Bun binary.

TAG CLASSES

toolchain

Attributes

NameDescriptionTypeMandatoryDefault
versionOverride Bun version. Defaults to the value in known_versions.bzl.Stringoptional""

bun_deps

bun_deps = use_extension("@rules_bun//bun:extensions.bzl", "bun_deps")
bun_deps.install(name, bun_version, ignore_scripts, install_flags, lock, package_json,
                 trusted_dependencies)

Bun-native node_modules staging — @<name>//:node_modules from a bun install --frozen-lockfile. Replaces aspect_rules_js’s npm_translate_lock + npm_link_all_packages for pure-Bun repos.

TAG CLASSES

install

Stage a node_modules tree from a package.json + bun.lock.

Attributes

NameDescriptionTypeMandatoryDefault
nameName of the generated repo. Reference its node_modules as @<name>//:node_modules.Namerequired
bun_versionBun version to fetch for the install. Empty = the toolchain extension’s default.Stringoptional""
ignore_scriptsSkip dependency lifecycle scripts (--ignore-scripts). Default True.BooleanoptionalTrue
install_flagsExtra raw flags appended to bun install.List of stringsoptional[]
lockThe bun.lock pinning the install (--frozen-lockfile).Labelrequired
package_jsonThe package.json to install from.Labelrequired
trusted_dependenciesPackages to --trust (run lifecycle scripts for) even when ignore_scripts is True.List of stringsoptional[]

Toolchain rule for rules_bun.

bun_toolchain wraps a single Bun binary as a Bazel toolchain. Consumers (the bun_test and bun_run rules) resolve Bun through @rules_bun//bun:toolchain_type, so users can register custom Bun binaries (locally-built fork, alternate version, baseline-CPU variant) via register_toolchains(...) without modifying rule attrs.

The module extension at @rules_bun//bun:extensions.bzl generates a default toolchain (@bun//:bun_toolchain_def) wrapping the prebuilt binary. Users register it from MODULE.bazel:

register_toolchains("@bun//:bun_toolchain_def")

bun_toolchain

load("@rules_bun//bun:toolchains.bzl", "bun_toolchain")

bun_toolchain(name, bun)

Declare a Bun binary as a Bazel toolchain.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
bunPath to the Bun executable.Labelrequired

BunToolchainInfo

load("@rules_bun//bun:toolchains.bzl", "BunToolchainInfo")

BunToolchainInfo(bun)

The Bun binary, resolved via a toolchain.

FIELDS

NameDescription
bunFile: the bun executable.