Buf CLI

Linting – Overview

Linting tools help to maintain the quality of code by enforcing a set of rules for style, syntax, and best practices. They can catch errors early, make the code easier to understand, and reduce the amount of manual code review required. The Buf CLI lints Protobuf files using a set of rules designed to encourage common conventions and maximize forward compatibility without restricting your organization's ability to adopt an in-house style guide.

This document provides an overview of Buf's Protobuf linting features.

We recommend completing the tour for an introduction to the buf lint command.

Key concepts

The Buf CLI's linter can check your schemas at two phases of development:

  • During development: You can integrate with your editor for immediate feedback as you're iterating, and also spot-check by running buf lint.
  • In code review: You can integrate with your CI/CD workflows (like GitHub Actions) to ensure that linting errors get flagged directly in your review flow without the need for constant human vigilance.

Rules and categories

The linter's rules are split up into categories, so choosing a strictness level is straightforward. We recommend using one of the predefined categories, but rules can also be selected individually to match more unusual policies. See the rules and categories page for detailed information.

The configuration categories, from strictest to most lenient, are:

  • DEFAULT
  • BASIC
  • MINIMAL

Changes that pass linting under a stricter policy also pass with all less-strict policies. For example, passing the DEFAULT rules means you will pass the MINIMAL rules. There are also two top-level categories outside of the strictness hierarchy that address comments and unary RPCs specifically.

Defaults and configuration

You configure lint rules in the buf.yaml configuration file, which is placed at the root of the Protobuf module it defines. If the input to buf lint doesn't contain a buf.yaml file, the Buf CLI operates as if there's a buf.yaml file with these values:

buf.yaml
version: v1
lint:
    use:
        - DEFAULT
    enum_zero_value_suffix: _UNSPECIFIED
    rpc_allow_same_request_response: false
    rpc_allow_google_protobuf_empty_requests: false
    rpc_allow_google_protobuf_empty_responses: false
    service_suffix: Service

Below is an example of each buf lint configuration option. For more information on specific options and the rules and categories, see the buf.yaml reference and the rules and categories page.

buf.yaml
version: v1
lint:
    use:
        - DEFAULT
    except:
        - FILE_LOWER_SNAKE_CASE
    ignore:
        - bat
        - ban/ban.proto
    ignore_only:
        ENUM_PASCAL_CASE:
            - foo/foo.proto
            - bar
        BASIC:
            - foo
    enum_zero_value_suffix: _UNSPECIFIED
    rpc_allow_same_request_response: false
    rpc_allow_google_protobuf_empty_requests: false
    rpc_allow_google_protobuf_empty_responses: false
    service_suffix: Service
    allow_comment_ignores: true

Usage examples

The Buf CLI can lint inputs beyond your local Protobuf files, such as Git repositories and tarballs. This can be useful in a variety of scenarios, such as using protoc output as Buf CLI input. Here are some example scripts:

# Lint output from protoc passed to stdin.
protoc -I . --include_source_info $(find . -name '*.proto') -o /dev/stdout | buf lint -

# Lint a remote Git repository on the fly and override its config to use your local config file.
buf lint 'https://github.com/googleapis/googleapis.git' --config buf.yaml

# Lint a module published to the Buf Schema Registry.
buf lint buf.build/acme/petapis

# Output lint error messages as JSON
buf lint --error-format=json

For remote locations that require authentication, see HTTPS Authentication and SSH Authentication.

Limit to specific files

By default, the Buf CLI builds all files under your buf.yaml configuration file, but you can choose to lint only specific files or directories. This is an advanced feature that's mostly intended to be used by other systems like editors. In general, it's better to let the Buf CLI discover all files and handle this for you. If you do need this, however, you can use the --path flag:

$ buf lint \
  --path path/to/foo.proto \
  --path path/to/bar.proto

You can also combine this with an inline configuration override:

$ buf lint \
  --path path/to/foo.proto \
  --path path/to/bar.proto \
  --config '{"version":"v1","lint":{"use":["BASIC"]}}'

Integration with CI/CD workflows

Because buf lint is part of a CLI, you can easily integrate it into CI/CD workflows. For instructions, see the General CI/CD setup and GitHub Actions pages.