Skip to content

Migrate from protoc#

The Buf CLI replaces a typical protoc workflow with two commands: buf build for compilation, buf generate for per-language code generation. Configuration moves out of long shell flags into two YAML files: buf.yaml for include paths, buf.gen.yaml for plugins.

This guide assumes you’re calling protoc directly from scripts or a Makefile. Install the Buf CLI before continuing. For other migration paths, see Protolock and Prototool.

A typical protoc setup#

Take a project with a primary module under proto/ and a vendored dependency under vendor/:

.
├── proto
│   └── acme
│       └── weather
│           └── v1
│               └── weather.proto
└── vendor
    └── google
        └── api
            └── annotations.proto

A common protoc invocation to generate Go and gRPC stubs:

$ protoc \
    -I proto \
    -I vendor \
    --go_out=. \
    --go_opt=paths=source_relative \
    --go-grpc_out=. \
    --go-grpc_opt=paths=source_relative \
    $(find proto -name '*.proto')

Each -I flag is a directory the compiler searches for imports. With these -I paths, proto/acme/weather/v1/weather.proto and vendor/google/api/annotations.proto are imported as acme/weather/v1/weather.proto and google/api/annotations.proto.

Convert -I paths to a buf.yaml workspace#

Each protoc -I path becomes a module in buf.yaml. Place buf.yaml at the directory that’s the common ancestor of every -I path; that directory is the workspace root.

.
├── buf.yaml
├── proto
│   └── acme
│       └── weather
│           └── v1
│               └── weather.proto
└── vendor
    └── google
        └── api
            └── annotations.proto
buf.yaml
version: v2
modules:
  - path: proto
  - path: vendor

For common dependencies such as googleapis, prefer a BSR dependency over vendoring when you can:

buf.yaml
version: v2
modules:
  - path: proto
deps:
  - buf.build/googleapis/googleapis

That keeps third-party schemas out of your repository, avoids counting vendored types as yours on paid BSR plans, and gives every workspace the same dependency version through buf.lock.

Verify the workspace compiles:

$ buf build

buf build reads buf.yaml from the current directory, discovers every .proto file in the configured modules, and compiles them. With no -o flag, the compiled output is discarded; pass -o lock.binpb to write a binary Buf image.

Convert plugin flags to a buf.gen.yaml#

Each --<lang>_out / --<lang>_opt pair from protoc becomes a plugins entry in buf.gen.yaml. Place the file alongside buf.yaml:

buf.gen.yaml
version: v2
plugins:
  - local: protoc-gen-go
    out: .
    opt:
      - paths=source_relative
  - local: protoc-gen-go-grpc
    out: .
    opt:
      - paths=source_relative

Run code generation:

$ buf generate

buf generate uses the same module discovery as buf build, so there’s no find invocation or explicit input list.

protoc flag reference#

protoc flag Buf equivalent Notes
-I <dir>, --proto_path=<dir> A modules[] entry in buf.yaml Each -I becomes a path: under modules.
--<lang>_out=<dir> plugins[].out in buf.gen.yaml Plus a plugins[].local: or remote: line for the binary or BSR plugin.
--<lang>_opt=<key>=<val> A plugins[].opt entry List of key=value strings under the same plugin.
--descriptor_set_out=FILE buf build -o FILE Writes a binary Buf image, wire-compatible with FileDescriptorSet. Add --as-file-descriptor-set to drop the extra Buf metadata.
--include_imports (default) buf build -o includes imports unless you pass --exclude-imports.
--include_source_info (default) Source code info is included unless you pass --exclude-source-info.
$(find <dir> -name '*.proto') (automatic) buf build and buf generate discover .proto files from the workspace; no explicit input list is needed.

Multiple generation templates#

If different parts of the schema need different generation settings (for example, a public API surface vs. a private one), invoke buf generate once per template using --template:

$ buf generate public --template buf.public.gen.yaml
$ buf generate private --template buf.private.gen.yaml

For details, see the buf generate reference.

What buf adds beyond protoc#

The Buf CLI covers steps protoc doesn’t:

  • buf lint: style and structural checks against a configurable rule set.
  • buf breaking: breaking-change detection against a previous schema (Git ref, BSR module, or stored image).
  • buf format: reformat .proto files in place.
  • The BSR: publish modules so they’re consumable by name from other workspaces, with generated SDKs in every supported language.