> ## Documentation Index
> Fetch the complete documentation index at: https://site.aspect.build/llms.txt
> Use this file to discover all available pages before exploring further.

# aspect buildifier

> Format Starlark BUILD, MODULE.bazel, and .bzl files with aspect buildifier, configured via format.alias() and buildifier_prebuilt in the Aspect CLI.

`aspect buildifier` formats Starlark files — `BUILD`, `BUILD.bazel`, `MODULE.bazel`, `.bzl`, `.axl`, `WORKSPACE`, and more — using the [buildifier](https://github.com/bazelbuild/buildtools/tree/main/buildifier) binary from [`buildifier_prebuilt`](https://registry.bazel.build/modules/buildifier_prebuilt).

It is currently registered as an alias of [`aspect format`](/docs/cli/tasks/format) via `format.alias()` in `.aspect/config.axl`. This makes it a first-class CLI command without any BUILD target or `rules_lint` dependency — just a `bazel_dep` on `buildifier_prebuilt` and a few lines of AXL.

Under the hood, `aspect buildifier` runs through the same `aspect format` infrastructure: the same change-detection logic, the same git snapshot technique, the same `--on-change` behavior, and the same artifact upload. The only difference is the formatter binary and the file pattern filter.

<Note>
  The alias setup below is the supported configuration today. A future release of the Aspect CLI may ship `aspect buildifier` as a built-in task that requires no `format.alias()` block — at which point the alias becomes optional. For now, follow the setup below.
</Note>

## Setup

**`MODULE.bazel`:**

```python theme={null}
bazel_dep(name = "buildifier_prebuilt", version = "8.5.1.2")
```

**`.aspect/config.axl`:**

```python theme={null}
load("@aspect//format.axl", "format")

buildifier = format.alias(
    defaults = {
        "formatter_target": "@buildifier_prebuilt//buildifier",
        # buildifier_binary is a symlink to the raw Go binary; it does not
        # switch to $BUILD_WORKING_DIRECTORY on its own, so we run it in
        # the user's cwd to make relative paths resolve.
        "run_in_cwd": True,
        # Fires only when the format task would otherwise pass zero files
        # to the formatter (e.g. `--scope=all`, or a `--scope=changed` run
        # that degraded because no changed files matched). The bare
        # buildifier binary needs `-r .` to walk the tree on its own. Inert
        # whenever a file list is passed, so `--scope=changed` (the default)
        # and per-file invocations are unaffected.
        "formatter_args_for_tree_walk": ["-r", "."],
        "include_patterns": [
            "**/BUILD",
            "**/BUILD.bazel",
            "**/MODULE.bazel",
            "**/*.MODULE.bazel",
            "**/WORKSPACE",
            "**/WORKSPACE.bazel",
            "**/*.axl",
            "**/*.bzl",
        ],
    },
    summary = "Format Starlark files using buildifier.",
)

def config(ctx: ConfigContext):
    ctx.tasks.add(buildifier)
```

This registers `aspect buildifier` as a real CLI command. Run it locally:

```shell theme={null}
aspect buildifier              # format changed Starlark files (default)
aspect buildifier --scope=all  # walk the tree and format every Starlark file
aspect buildifier BUILD.bazel  # format specific files explicitly
```

<Warning>
  **`--scope=all` covers a narrower file set than `--scope=changed`.** In `--scope=all` the format task hands off discovery to buildifier's `-r .` tree walk, which has a hard-coded list of recognized file types: `BUILD`, `BUILD.bazel`, `MODULE.bazel`, `WORKSPACE`, `WORKSPACE.bazel`, `*.bzl`, `*.star`. Files matching the alias's `include_patterns` but not on buildifier's list — notably `*.axl`, `*.MODULE.bazel`, `Tiltfile`, `BUCK` — are **silently skipped**. `include_patterns` filters the changed-file list in `--scope=changed` and the post-format diff in both modes, but it does not extend buildifier's tree walk.

  In `--scope=changed` (the default) the task passes the changed file list to buildifier positionally, so every extension in `include_patterns` is formatted. The same applies when you pass files explicitly (`aspect buildifier path/to/file.axl`).

  For a CI job that needs full coverage of an extension buildifier doesn't auto-discover, prefer `--scope=changed` against a broader base ref, or invoke buildifier on the file set yourself.
</Warning>

## Configuration

All [aspect format](/docs/cli/tasks/format) configuration applies: `--scope`, `--on-change`, `--ignore-pattern`, `--upload-format-diff`. The `format.alias()` defaults bake in the formatter target and file patterns so you don't repeat them at invocation time.

To add or remove file patterns from the defaults:

```python title=".aspect/config.axl" theme={null}
buildifier = format.alias(
    defaults = {
        "formatter_target": "@buildifier_prebuilt//buildifier",
        "include_patterns": [
            "**/BUILD",
            "**/BUILD.bazel",
            "**/*.bzl",
            # omit .axl and .star if you don't use those extensions
        ],
    },
    summary = "Format Starlark files using buildifier.",
)
```

## CI examples

The `--task:name` matches the alias name you registered:

<CodeGroup>
  ```yaml GitHub Actions theme={null}
  on:
    pull_request:
      branches: [main]

  jobs:
    buildifier:
      runs-on: [self-hosted, aspect-workflows, aspect-default]
      permissions:
        id-token: write
      steps:
        - uses: actions/checkout@v6
        - uses: aspect-build/setup-aspect@2306377a61c45954ab2df7c7311698b109364352 # v2026.26.9
          with:
            aspect-api-token: ${{ secrets.ASPECT_API_TOKEN }}
        - run: aspect buildifier --task:name buildifier
  ```

  ```yaml Buildkite theme={null}
  steps:
    - label: ":starlark: Buildifier"
      plugins:
        - aspect-build/setup-aspect#1d5768c5d28b72bf523b4722fc9177d2cc2d85c7: ~ # v2026.26.8
      command: aspect buildifier --task:name buildifier
      agents:
        queue: aspect-default
  ```

  ```yaml GitLab theme={null}
  include:
    - component: $CI_SERVER_FQDN/aspect-build/setup-aspect-gitlab-component/setup@2026.26.8

  buildifier:
    extends: .setup-aspect
    tags: [aspect-workflows, aspect-default]
    rules:
      - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
    script: aspect buildifier --task:name buildifier
  # Set ASPECT_API_TOKEN as a masked CI/CD variable.
  ```

  ```yaml CircleCI theme={null}
  version: 2.1

  orbs:
    setup-aspect: aspect-build/setup-aspect@2026.26.10

  jobs:
    buildifier:
      machine: true
      resource_class: circleci-org/aspect-default
      steps:
        - checkout
        - setup-aspect/setup
        - run: aspect buildifier --task:name buildifier
  ```
</CodeGroup>
