As you evolve your Protobuf schemas, it's easy to mistakenly introduce breaking changes—either by breaking your generated code, or by breaking your ability to read existing data. The Buf CLI identifies these problematic changes immediately, allowing you to carefully consider whether the breakage is warranted.

The tutorial will take you through running breaking change detection and demonstrate common use cases.

Prerequisites

We recommend completing the Buf CLI tour to get an overview of the Buf CLI first.

  • Install the Buf CLI
  • Have at least 1 directory containing .proto files

Define a module

Modules represent a collection of files that are configured, built, and versioned as a logical unit when performing buf operations. Define a module by adding a buf.yaml config file to the directory of the .proto files you want to group together.

$ cd /path/to/your/directory
$ buf mod init

For example:

.
└── acme
    └── weather
        └── v1
            ├── buf.yaml
            └── weather.proto

buf mod init creates a basic buf.yaml file with all of the required elements:

buf.yaml
version: v1
breaking:
  use:
    - FILE
lint:
  use:
    - DEFAULT

This new module is your input for the buf breaking commands in the rest of the tutorial.

For more information about specific fields, see the buf.yaml reference.

Compare against a local Git repository

Run buf breaking on your module by specifying the file path to the directory containing the buf.yaml and choosing an input to compare it against. For example, you can target the module you just defined and compare it against the main branch of your local git repository:

$ buf breaking --against 'path/to/your/git/root/.git#branch=main'

The Buf CLI returns any errors in a file:line:column:message format by default:

$ buf breaking --against '.git#branch=main'
Output
pet/v1/pet.proto:18:3:Field "1" on message "Pet" changed type from "enum" to "string".

You can also output the errors as JSON:

$ buf breaking --against '.git#branch=main' --error-format=json
Output
{"path":"acme/pet/v1/pet.proto","start_line":18,"start_column":3,"end_line":18,"end_column":9,"type":"FIELD_SAME_TYPE","message":"Field \"1\" on message \"Pet\" changed type from \"enum\" to \"string\"."}

Compare against the Buf Schema Registry

If you're already using the BSR, you can check against the module that represents the package you're working on.

$ buf breaking --against <BSR_SERVER>/<ORGANIZATION>/<MODULE>
Example: buf breaking --against buf.build/acme/petapis