buf vs protoc: Modern Protobuf Tooling vs the Compiler
protoc is the official Protocol Buffers compiler; buf wraps and modernizes the workflow with linting, breaking-change detection, and dependency management.
protoc compiles .proto files to code via plugins, but managing includes, plugins, and consistency is manual. buf provides a higher-level workflow (buf.yaml, lint, breaking-change checks, remote plugins, a schema registry) on top of the same compilation.
| buf | protoc | |
|---|---|---|
| Role | Workflow: lint, breaking, generate | Reference compiler |
| Linting | Built in | None |
| Breaking-change detection | Built in | None |
| Dependency management | buf.yaml + registry | Manual include paths |
| Config | buf.yaml / buf.gen.yaml | Command-line flags / scripts |
Where buf wins
buf turns protobuf into a managed workflow: it lints schemas against style rules, detects breaking changes against a baseline, manages dependencies, and generates code with a clear config. In CI this catches incompatible API changes before they ship, which raw protoc cannot do.
Where protoc still fits
protoc is the canonical compiler and remains the right choice for minimal setups, unusual plugins, or environments where you do not want another tool. buf ultimately relies on the same generation concepts, and some pipelines are simple enough that scripted protoc is sufficient.
In CI
A common pipeline runs buf lint and buf breaking on every PR, then buf generate. This gives schema quality gates that protoc lacks. If you only need code generation and have a stable plugin setup, protoc plus a script works.
The verdict
Use buf when you want protobuf linting, breaking-change detection, and managed dependencies in CI; use protoc for minimal or unusual generation needs. Most teams maintaining shared schemas benefit from buf.