The Buf CLI is a helpful tool for managing Protobuf schemas. It offers various features, including code generation, breaking change detection, linting, and formatting, to assist with Protobuf development and maintenance. It works with your choice of plugins and languages and gives you access to a vast library of certified plugins in the Buf Schema Registry.
Buf CLI commands
The links below go to detailed usage guides. See the Buf CLI reference for complete options and flags for each command.
build
: Build Protobuf files into a Buf image (key to many otherbuf
operations)generate
: Generate code stubs from Protobuf files usingprotoc
pluginsbreaking
: Verify no breaking changes have been made, to guard against compatibility issueslint
andformat
: Lint and format your Protobuf files according to best practice and your org rulescurl
: Test your APIs by invoking an RPC endpoint, similar to usingcURL
convert
: Convert a message from binary to JSON or vice versa—useful when debugging or testingmod
,registry
,push
, andexport
: Manage your repositories in the Buf Schema Registry
Configuration
The Buf CLI interacts with several configuration files depending on the operation.
buf.yaml
buf.yaml
is used to define a module. It's the primary configuration file, and is
responsible for the module's name, dependencies, and lint
and breaking
configuration.
buf.lock
buf.lock
contains the module's dependency manifest, and represents a single, reproducible build of your module's
dependencies.
buf.gen.yaml
buf.gen.yaml
is used to define a local plugin template that works directly with the buf generate
command to
generate code stubs from your Protobuf files.
buf.work.yaml
buf.work.yaml
is used to define a workspace, which is an advanced local development
feature. Workspaces make it possible to consolidate one or more modules into a single buildable unit. They also allow
users to run buf
operations across multiple modules with a single execution (such as buf lint
).
Default configuration
The default configuration location depends on the input. If buf
is executed with an input that
contains buf.{mod,lock,work}
files, those files are used for the given operation. Running buf lint
, for example,
would use the lint
configuration found in the inputs buf.yaml
, if it exists.
If a buf.yaml
file is not contained in the input, buf
operates as if there is a buf.yaml
file with the
default values. The buf.{lock,work}
files do not have a default value.
It's important to note that, unlike the buf.{mod,lock,work}
files, the buf.gen.yaml
file found in the input is
not used by default. Instead, the buf.gen.yaml
found in the current working directory is used by default. You
can manually specify the buf.gen.yaml
file to use with the --template
flag, which is explained further in the
generate usage. The buf.gen.yaml
file does not have a default value, so running buf generate
without a buf.gen.yaml
file in the current working directory yields an error (unless a --template
is explicitly
specified).
Configuration override
Specifying an alternative configuration location is an advanced feature and is not necessary in most cases.
Many of the buf
commands support a --config
flag that's used to override the buf.yaml
configuration with a file
path or direct JSON or YAML data. This is useful for situations where you may want to specify all options via the
command line, for example with Bazel integrations and/or when using the protoc
plugins.
All commands have one or more --.*config
flags that control this behavior. For example:
buf build --config
specifies the config for the source input.buf lint --config
specifies the config for the source or Buf image input.buf breaking --config
specifies the config for the source or image input.buf breaking --against-config
specifies the config for the source or image input to compare against.
The value of this flag is interpreted as follows:
- If the value ends in
.json
, this is interpreted to be a local path to a JSON file. - If the value ends in
.yaml
, this is interpreted to be a local path to a YAML file. - Otherwise, this is interpreted to be either JSON or YAML data, which is directly parsed.
For example:
# Read the JSON file foo/bar.json.
buf lint --config foo/bar.json
# Read the YAML file foo/bar.yaml.
buf lint --config foo/bar.yaml
# Use the given JSON data.
# This results in only using the ENUM_NO_ALLOW_ALIAS lint rule for linting.
buf lint --config '{"version":"v1","lint":{"use":["ENUM_NO_ALLOW_ALIAS"]}}'