The buf.gen.yaml
file defines a local plugin template, and is used by the
buf generate
command to generate code for the language(s) of your choice. This
file is often used with a module (or another
input), and is typically placed next to your
buf.work.yaml
file:
.
├── buf.gen.yaml
├── buf.work.yaml
├── acme
│  └── pet
│ └── v1
│  └── pet.proto
├── buf.lock
└── buf.yaml
An example of the buf.gen.yaml
file used to generate Go/gRPC stubs is shown
below:
version: v1
plugins:
- plugin: go
out: gen/proto/go
opt: paths=source_relative
- plugin: buf.build/grpc/go:v1.2.0
out: gen/proto/go
opt:
- paths=source_relative
- require_unimplemented_servers=false
version
The version
key is required, and defines the current configuration
version. The only accepted values are v1beta1
and v1
.
plugins
Each entry in the buf.gen.yaml
plugins
key is a protoc
plugin
configuration, which is a program that generates code by interacting with the
compiled representation of your module.
plugin
plugin
is required.
Local Plugins:
To execute a locally installed plugin, specify the plugin name via the
plugin
field. All protoc
plugins begin with the protoc-gen-
prefix.
By default, a protoc-gen-<name>
program is expected to be on your PATH
so
that it can be discovered and executed by buf
. This can be overridden with the
path option shown below.
Remote Plugins:
The plugin
field can specify a remotely executed
plugin (<remote>/<owner>/<plugin-name>:<plugin-version>
or
<remote>/<owner>/<plugin-name>
). If a remotely executed plugin omits the
<plugin-version>
, the latest version will be used. If a <plugin-version>
is
specified, the optional revision can be specified
to pin an exact revision of a plugin version.
out
The out
of a plugin is required, and controls where the generated files
are deposited for a given plugin. Although absolute paths are supported, this
configuration is traditionally a relative output directory that depends on where
buf generate
is run. For example, running buf generate
from the root of the
tree
shown above would result in a new gen/proto/go
directory within the
same root:
buf generate
tree
.
├── acme
│  └── pet
│ └── v1
│  └── pet.proto
├── gen
│  └── proto
│ └── go
│  └── ...
├── buf.gen.yaml
├── buf.lock
└── buf.yaml
opt
The opt
of a plugin is optional, and specifies one or more protoc
plugin
options for each plugin independently. In the buf.gen.yaml
example above, this
is relevant for both protoc-gen-go
and protoc-gen-go-grpc
. As you can see,
you can provide options as either a single string or a list of strings.
path
The path
of a plugin is optional, and overrides the default location and
explicitly specify where to locate the protoc
plugin. For example, if another
custom plugin called protoc-gen-foo
is not located on your PATH
, but is
found at bin/proto/protoc-gen-foo
, you can refer to it like this:
version: v1
plugins:
- plugin: foo
out: gen/foo
path: bin/proto/protoc-gen-foo
The path can include some arguments. If the path has more than one element, the
first is the plugin binary and the others are optional additional arguments to
pass to the binary. For example, you can run the version of protoc-gen-go
that matches the google.golang.org/protobuf
specified by go.mod
by:
version: v1
plugins:
- name: go
path: ["go", "run", "google.golang.org/protobuf/cmd/protoc-gen-go"]
out: gen/proto
opt: paths=source_relative
This field only works with local plugins.
revision
The revision
is optional and may be used along with the plugin
field to
pin an exact version of a remote plugin. In most cases, it is recommended to
omit the revision
, in which case the latest revision of the plugin will be
used (automatically pulling in the latest bug fixes).
Below is an example of using the revision to target an exact version of a plugin:
version: v1
plugins:
- plugin: buf.build/protocolbuffers/go:v1.28.1
revision: 1
out: gen/proto/go
opt: paths=source_relative
strategy
Your strategy
of a plugin is optional, and specifies the generation
strategy
for buf generate
to use. For example, we can add a strategy
to
one of the plugins in the configuration shown above like this:
version: v1
plugins:
- plugin: go
out: gen/proto/go
opt: paths=source_relative
- plugin: go-grpc
out: gen/proto/go
opt:
- paths=source_relative
- require_unimplemented_servers=false
strategy: directory
There are two options:
directory
(default for local plugins)
This results in buf
splitting the input files by directory and making separate
plugin invocations in parallel. That's roughly the concurrent equivalent of this
operation:
$ for dir in $(find . -name '*.proto' -print0 | xargs -0 -n1 dirname | sort | uniq); do
protoc -I . $(find "${dir}" -name '*.proto')
done
Almost every protoc
plugin either requires this, so this is the recommended
strategy
. The directory
strategy is used by default if omitted for local plugins.
Remote plugins use all
for every invocation.
all
This results in buf
making a single plugin invocation with all input files,
which is roughly equivalent to this:
$ protoc -I . $(find . -name '*.proto')
This is needed for certain plugins that expect all files to be given at once. It is also used for remote plugin generation to improve code generation performance.
protoc_path
The protoc_path
of a plugin is optional and only applies to the code generators
that are built-in to protoc
. Normally, a plugin is a separate executable whose
binary name is like protoc-gen-<name>
. But for a handful of plugins, the executable
used is protoc
itself. The following plugins result in invoking protoc
instead of
a dedicated plugin binary:
cpp
csharp
java
js
(before v21)kotlin
(after v3.17)objc
php
pyi
python
ruby
Normally for the above plugins, buf
will execute the protoc
binary that is found in
your $PATH
. But this configuration option lets you point to a specific binary. This
is particularly useful if you need to support a specific version of protoc
, which
could differ from the version in $PATH
. For example, you can run a specific version of
protoc
instead of the protoc
installed in $PATH
by:
version: v1
plugins:
- plugin: go
revision: 1
out: gen/proto/go
protoc_path: /path/to/specific/version/bin/protoc
managed
The managed
key is used to configure
managed mode and is an advanced feature. A
complete example of the managed
configuration with the protoc-gen-go
plugin
is shown below:
version: v1
managed:
enabled: true
cc_enable_arenas: false
java_multiple_files: false
java_package_prefix: com
java_string_check_utf8: false
optimize_for: CODE_SIZE
go_package_prefix:
default: github.com/acme/weather/private/gen/proto/go
except:
- buf.build/googleapis/googleapis
override:
buf.build/acme/weather: github.com/acme/weather/gen/proto/go
override:
JAVA_PACKAGE:
acme/weather/v1/weather.proto: "org"
plugins:
- plugin: go
out: gen/proto/go
opt: paths=source_relative
enabled
The enabled
key is required if any other managed
keys are set. Setting
enabled
equal to true
enables managed mode
according to
default behavior.
cc_enable_arenas
The cc_enable_arenas
key is optional, and controls what the
cc_enable_arenas
value is set to in all of the files contained within the generation target
input. The only accepted values are false
and true
.
java_multiple_files
The java_multiple_files
key is optional, and controls what the
java_multiple_files
value is set to in all of the files contained within the generation target
input. The only accepted values are false
and true
.
java_package_prefix
The java_package_prefix
key is optional, and controls what the
java_package
prefix value is set to in all of the files contained within the generation
target input. By default, the value is com
.
java_string_check_utf8
The java_string_check_utf8
key is optional, and controls what the
java_string_check_utf8
value is set to in all of the files contained within the generation target
input. The only accepted values are false
and true
.
optimize_for
The optimize_for
key is optional, and controls what the
optimize_for
value is set to in all of the files contained within the generation target
input. The only accepted values are SPEED
, CODE_SIZE
and LITE_RUNTIME
. If
omitted, the default value, SPEED
, is used.
go_package_prefix
The go_package_prefix
key is optional, and controls what the
go_package
value is set to in all the files contained within the generation target input.
default
The default
key is required if the go_package_prefix
key is set. The
default
value is used as a prefix for the go_package
value set in each of
the files. The default
value must be a relative filepath that must not
jump context from the current directory, that is they must be subdirectories
relative to the current working directory. As an example, ../external
is
invalid.
In the configuration example shown above, the
github.com/acme/weather/gen/proto/go
prefix is joined with the given
Protobuf file's relative path from the module root. In the
buf.build/acme/weather
module's case, the acme/weather/v1/weather.proto
file
would have this go_package
set:
syntax = "proto3";
package acme.weather.v1;
option go_package = "github.com/acme/weather/gen/proto/go/acme/weather/v1;weatherv1";
If the Protobuf file's package declaration conforms to the
PACKAGE_VERSION_SUFFIX
lint rule, the final two path elements are concatenated and included after the;
element in thego_package
result. The above example generates a Go package with a package declaration equal toweatherv1
, which enables you to import Go definitions from a variety of generated packages that would otherwise collide (a lot of Protobuf packages contain thev1
suffix).
except
The except
key is optional, and removes certain modules from the
go_package
file option override behavior. The except
values must be
valid module names.
There are situations where you may want to enable
managed mode for the go_package
option in
most of your Protobuf files, but not necessarily for all of your Protobuf
files. This is particularly relevant for the buf.build/googleapis/googleapis
module, which points its go_package
value to an
external repository. Popular
libraries, such as grpc-go depend on these
go_package
values, so it's important that managed mode does not overwrite
them.
override
The override
key is optional, and overrides the go_package
file option
value used for specific modules. The override
keys must be valid module
names. Additionally, the corresponding override
values must be a valid
Go import path and must not jump
context from the current directory. As an example, ../external
is invalid.
This setting is used for workspace
environments, where you have a module that imports from another module in the
same workspace, and you need to generate the Go code for each module in
different directories. This is particularly relevant for repositories that
decouple their private API definitions from their public API definitions (as is
the case for buf
).
override
This is a list of per-file overrides for each modifier. In the example provided
above, an override for acme/weather/v1/weather.proto
is set for the
java_package_prefix
modifier to be org
instead of com
. This sets org
as
the package prefix for only the specific acme/weather/v1/weather.proto
file and not for the rest of the module.