Protobuf Editions replaces the old proto2 and proto3 syntax switch with individual feature settings. Instead of upgrading a whole file at once, you can change behaviors one at a time:
- Field Presence: whether a reader can tell a field that was never set apart from one set to its default value. Choose
IMPLICIT(the proto3 behavior) orEXPLICIT(the proto2 behavior); the Field Presence page covers the tradeoff. - Enum Type: where a value the enum does not declare ends up.
OPENkeeps it in the field;CLOSEDmoves it to the unknown fields. - Repeated Encoding: Standardize on
PACKED(for efficiency) orEXPANDED(for compatibility).
Under proto2 and proto3, these behaviors came as a set with the syntax keyword at the top of the file, so migration was all or nothing. Moving a file to proto3 opened its closed enums, dropped its custom field defaults, and removed explicit presence from its singular scalars.
Editions makes each of those a separate feature. A feature can be set for a whole file and then overridden on the elements it applies to, such as one enum for enum type or one field for field presence, so a schema can adopt one new behavior without taking the others. New behavior ships as a new feature with a per-edition default, so there is no "proto4" forcing another migration of every behavior at once.
Three editions have shipped so far: edition 2023, which unified proto2 and proto3; edition 2024, which added symbol visibility, import option, and naming-style enforcement; and edition 2026 (protobuf 36.x), which tightens the naming rules, defaults symbol visibility to strict, and adds custom JSON names for enum values. The editions overview and the feature settings reference track exactly what each edition changes.
edition = "2024"; package demo.v1; // Set for the whole file... option features.enum_type = CLOSED; enum Unit { UNIT_UNSPECIFIED = 0; UNIT_CELSIUS = 1; } enum Status { // ...and overridden on one enum. option features.enum_type = OPEN; STATUS_UNSPECIFIED = 0; STATUS_ACTIVE = 1; }
Edition by edition
No edition changes the wire format. A field is encoded the same way under proto3, edition 2023, and edition 2026, and a reader on any of them can parse what a writer on any other produced. The bytes can still differ where the defaults do: a field explicitly set to zero is written under explicit presence, the editions default, and skipped under proto3's implicit presence. Editions change defaults and language rules instead, such as how an unset field behaves, which schemas the compiler accepts, and the shape of the generated code. Moving a file forward is an edit to its first line, plus explicit features wherever the new defaults would change the file's behavior; the compiler reports anything it cannot carry over.
How the language got here
Protobuf has been public since 2008. These are the releases that changed the language, from proto2 through editions.
Further Reading
- Protobuf Editions are here: don't panic
An overview of editions for teams on proto2 or proto3, and how to migrate.
Next
Standard Options
Protobuf options at the file, message, and field level: what the well-known options do and how options change generated code without changing the wire format.