# Protobuf: a serialization format you install as a compiler plus ten runtimes

> The format is language-neutral, but the installation is not one thing. protoc exists as a pre-built binary only for released versions, three of the ten language runtimes live in other repositories, and the README tells you plainly not to build from the main branch.

**protocolbuffers/protobuf** — Google's language-neutral, platform-neutral mechanism for serializing structured data, combining the protoc compiler with runtimes for many programming languages.

- Repository: https://github.com/protocolbuffers/protobuf
- Website: http://protobuf.dev
- Stars: 72,078 · Forks: 16,297
- Language: C++
- License: not declared
- Published: 2026-08-08 · Updated: 2026-08-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/protocolbuffers-protobuf

## Installation is a compiler plus a runtime, not one package

The framing at the top of the README is the thing to internalise before anything else. To use protobuf you install two separate pieces: the protocol compiler, which compiles `.proto` files, and the protobuf runtime for your chosen programming language. The compiler is written in C++, and language runtimes are installed from their own source directories rather than from a single bundle.

That split shapes your build. `protoc` is a build-time tool that turns a schema into generated code, while the runtime is a library your service links against at run time, and the two come from different places and can be on different versions. For non-C++ users the compiler is easy: each release on the GitHub releases page ships a zip named `protoc-$VERSION-$PLATFORM.zip` containing the `protoc` binary together with the standard `.proto` files that ship with protobuf. The runtime side is per language, and the README's table is the index.

## Pre-built protoc binaries stop at the last release

Pre-built compiler binaries are provided only for released versions, and the README is explicit about the three cases where that stops being enough. If you want the GitHub main version at HEAD, if you need to modify protobuf code, or if you are using C++, the recommendation is to build your own `protoc` from source, following the C++ installation instructions in `src/README.md`.

The consequence is a hard cutoff in your dependency story. A released version is a download, but anything past the last tag, or any local patch to the compiler, means a C++ toolchain, a build of protobuf itself, and a rebuild whenever you move. There is a partial escape hatch for old versions rather than new ones: a release you need that is not on the releases page can be fetched as a Maven artifact from `repo1.maven.org/maven2/com/google/protobuf/protoc/`. The direction of that workaround is worth noticing, because it helps you pin backwards and does nothing for you at HEAD.

## The README tells you not to build from the main branch

The guidance on working with protobuf source is unusually blunt. Most users are pointed at the supported releases as the easiest path. If you choose the head revision of the main branch, the build will occasionally be broken by source-incompatible changes and insufficiently-tested behaviour. If you are using C++ or otherwise need to build protobuf from source as part of your project, you should pin to a release commit on a release branch.

The second half is the part people quote, and it carries a caveat that is easy to skim past: even release branches can experience some instability in between release commits. So the unit you pin is a specific release commit, not a branch, which means your build stops following the branch automatically. The consequence is that a C++ consumer owns its protobuf patch stream, and the current release line is v36.2, published 2026-09-17, after v36.1 on 2026-08-31 and v36.0 on 2026-08-20.

## Three of the ten language runtimes are in other repositories

The runtime table lists ten languages, and seven of them are directories in this repository: C++ under `src`, plus `java`, `python`, `objectivec`, `csharp`, `ruby` and `php`. The other three are not. Go lives in protocolbuffers/protobuf-go, Dart in dart-lang/protobuf, and JavaScript in protocolbuffers/protobuf-javascript.

The consequence is that a single checkout is not a single dependency. Teams using more than one of those three languages are combining version numbers from four repositories, and a protobuf upgrade is a coordinated operation rather than one bump. The examples directory reinforces the split, since it carries `add_person.cc`, `add_person.py`, `add_person.rb`, `add_person.dart`, `list_people.cc` and Java and Go equivalents alongside `addressbook.proto`, with no C#, PHP, Objective-C or JavaScript example alongside them. There is also a `lua/` directory in the tree that the runtime table does not mention.

## Bazel users have to support two dependency systems at once

Protobuf supports Bzlmod with Bazel 8 and newer, declared in a MODULE.bazel file:

```
bazel_dep(name = "protobuf", version = <VERSION>)
```

The repository name can be overridden when you need compatibility with WORKSPACE, which is the second supported path:

```
http_archive(
    name = "com_google_protobuf",
    strip_prefix = "protobuf-VERSION",
    sha256 = ...,
    url = ...,
)

load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")

protobuf_deps()

load("@rules_java//java:rules_java_deps.bzl", "rules_java_dependencies")

rules_java_dependencies()

load("@rules_java//java:repositories.bzl", "rules_java_toolchains")

rules_java_toolchains()

load("@rules_python//python:repositories.bzl", "py_repositories")

py_repositories()
```

The cost of the legacy path is called out directly: with the release of 30.x there are a few more load statements needed to properly set up rules_java and rules_python, which is why `rules_java_dependencies()`, `rules_java_toolchains()` and `py_repositories()` all appear above. The consequence is that a project on WORKSPACE carries more setup than one on Bzlmod, and that setup grows as protobuf releases add dependencies. The tree reflects the weight of this, with `.bazelrc`, `.bazeliskrc`, `bazel9.bazelrc`, `WORKSPACE`, `WORKSPACE.bzlmod` and a `.bazelci/` directory side by side.

## The tree carries a conformance suite, benchmarks and Google-internal scripts

The top level makes clear that protobuf is a multi-language build system rather than a single library. Alongside the language directories sit `conformance/`, which is a test suite for implementations, `compatibility/`, `benchmarks/`, `editions/`, `build_defs/`, `editors/`, `hpb/` with its `hpb_generator/`, and `patches/` containing a `Disable_bundle_install.patch`.

Several entries have no meaning outside Google, and that is worth naming rather than skipping. `google3_export_generated_files.sh` exports generated files into Google's internal tree, `generate_descriptor_proto.sh` regenerates protobuf's own descriptor schema, `fix_permissions.sh` handles repository permissions, and `PrivacyInfo.xcprivacy` and `Protobuf.podspec` exist for Apple platforms. The consequence for an outside contributor is that the repository is bigger and stranger than a serialization format needs to be, and that onboarding means working out which of these directories matter for a change you are making.

## Copyright 2008 Google LLC, with support windows documented on another page

The README carries a Copyright 2008 Google LLC line, and the repository ships a LICENSE file at the top level, though GitHub's own classification of the project comes back as NOASSERTION rather than a standard identifier, so automated licence checks come back empty and the terms have to be read directly.

Support is handled by a separate mechanism from releases. Rather than describing lifecycles in the README, the project points at a version support policy page for support timeframes on the language libraries, and the core repository's own release cadence is its own thing, with v36.0, v36.1 and v36.2 landing inside a month. The consequence is that the age of the core repository tells you nothing about how long a given language library will be supported, and that the two questions have to be asked separately. Community discussion runs through a Google Group for protobuf.

## Conclusion

Protobuf is a sound choice when several languages and services have to agree on a wire format, and the reference implementation is careful about the things that bite people: it tells you to pin a release commit, it publishes the compiler as a versioned artifact, and it documents a support policy per language library. Two costs are real. Pre-built protoc binaries stop at the last release, so anything on the main branch or any local patch means owning a C++ build of the compiler. And Go, Dart and JavaScript runtimes are separate repositories with their own version numbers. Before you adopt it, check three things: which release tag you are pinning, which runtime repository each of your languages actually comes from, and what the version support policy says about the languages you are standardising on.

## FAQ

### What is Protobuf used for?

Protocol Buffers are Google's language-neutral, platform-neutral, extensible mechanism for serializing structured data. You describe your data in `.proto` files, compile them with the protocol compiler, and use the generated code with the runtime for your language.

### How do I install protobuf?

You need two things: the protocol compiler that compiles `.proto` files, and the runtime for your language. For non-C++ users the simplest route is a pre-built binary from the GitHub release page, packaged as `protoc-$VERSION-$PLATFORM.zip` and containing the `protoc` binary plus the standard `.proto` files, while runtime instructions live in each language's source directory.

### How do I use protobuf in Go?

The Go runtime is not in the main repository. It lives in protocolbuffers/protobuf-go, which means your Go dependency is versioned separately from the C++ compiler and runtime in this repository. The main repository's examples directory does include a Go example alongside `addressbook.proto`.

### How do I use protobuf in Python?

Python installation instructions live in the `python` source directory of the repository, and the recommended learning path is the tutorials in the developer guide at protobuf.dev rather than the README. Runnable code lives in the `examples` directory, which includes `addressbook.proto`, `add_person.py` and `list_people.py`.

### Is Protobuf better than JSON?

The README does not make that comparison. What it does set out is the cost of adopting protobuf: you install a protocol compiler to compile `.proto` files and a runtime for your language, you pin to a release commit rather than the main branch, and pre-built compiler binaries are published only for released versions.

## Sources

- [Official documentation](http://protobuf.dev)
- [Official README](https://github.com/protocolbuffers/protobuf#readme)
- [Project repository](https://github.com/protocolbuffers/protobuf)
- [Release notes](https://github.com/protocolbuffers/protobuf/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/protocolbuffers-protobuf
