Pure Go alternative to protocol buffers with minimum code generation
Go
41
71 commits
updated Sep 9, 2026
Prutal is a pure Go alternative to protocol buffers, it covers most of the functionality offered by Protocol Buffers.
Prutal aims to minimize code generation as much as possible while ensuring serialization and maintaining good performance.
Since Prutal is NOT yet ready for production use, we are not providing usage documentation at this time, nor do we guarantee backward compatibility of the interface.
| Features | Prutal | Protobuf |
|---|---|---|
| Supported Languages | Go | C++, Java, Python, Go, and more |
| Code Generation | ✅ | ✅ |
| Generated Code Size | 😄 compact | 😡 bulky |
| Serialization | ✅ | ✅ |
| Performance | ⭐️⭐️⭐️⭐️⭐️ | ⭐️⭐️⭐️ |
| Extensibility | 😄 Package | 😡 Plugin |
| Compatibility | ✅ (see Protobuf Compatibility) | ✅ |
| gRPC | ✅ | ✅ |
| Non-Pointer Field | ✅ (aka gogoproto.nullable) | ❌ |
protoc-gen-go), open API and hybrid API without the protoopaque build tagdefault_api_level=API_OPAQUE, or the hybrid API built with -tags protoopaque): field presence lives in a bitmap the runtime does not maintainallow_alias)bytes field is read from the struct tag as protoc-gen-go writes it:
a field of a proto3 file carries proto3, a proto3 optional field oneof on top of it,
and any other singular field has presence.prutalgen writes the same markers, plus its own implicit marker
for an edition 2023 field with features.field_presence = IMPLICIT,
which protoc-gen-go leaves unmarked.prutalgen versions carries no markers and is read as having presence:
a bytes field without presence, proto3 or editions implicit,
holding an empty non-nil slice is serialized as an empty field instead of being skipped.
Decoders read it as the default value; regenerate to get the exact output.protoc-gen-go output for an edition 2023 implicit bytes field has the same divergence,
as the runtime cannot tell it from a field with presence.protojson equivalentprototext)protoreflect)protoregistry)dynamicpb)protobuf-go are dropped by Marshal; on Unmarshal they are kept as unknown fields and written back as suchprutalgen)google.golang.org/protobuf/types/known, Any is limitedUse pkg/grpccodec and pass grpccodec.PrutalCodec to the gRPC v1 codec APIs on both server and client.
See pkg/grpccodec/README.md for usage details and tests/cases/grpc for a complete example.
Contributor guide: Contributing.
Prutal is licensed under the terms of the Apache license 2.0. See LICENSE for more information.
Dependencies used by prutal are listed under licenses.
232 followers · starred Oct 2025
25 followers · starred Apr 2025
37 followers · starred Feb 2025
3 followers · starred Oct 2025
Pure Go alternative to protocol buffers with minimum code generation
Go
41
71 commits
updated Sep 9, 2026
Prutal is a pure Go alternative to protocol buffers, it covers most of the functionality offered by Protocol Buffers.
Prutal aims to minimize code generation as much as possible while ensuring serialization and maintaining good performance.
Since Prutal is NOT yet ready for production use, we are not providing usage documentation at this time, nor do we guarantee backward compatibility of the interface.
| Features | Prutal | Protobuf |
|---|---|---|
| Supported Languages | Go | C++, Java, Python, Go, and more |
| Code Generation | ✅ | ✅ |
| Generated Code Size | 😄 compact | 😡 bulky |
| Serialization | ✅ | ✅ |
| Performance | ⭐️⭐️⭐️⭐️⭐️ | ⭐️⭐️⭐️ |
| Extensibility | 😄 Package | 😡 Plugin |
| Compatibility | ✅ (see Protobuf Compatibility) | ✅ |
| gRPC | ✅ | ✅ |
| Non-Pointer Field | ✅ (aka gogoproto.nullable) | ❌ |
protoc-gen-go), open API and hybrid API without the protoopaque build tagdefault_api_level=API_OPAQUE, or the hybrid API built with -tags protoopaque): field presence lives in a bitmap the runtime does not maintainallow_alias)bytes field is read from the struct tag as protoc-gen-go writes it:
a field of a proto3 file carries proto3, a proto3 optional field oneof on top of it,
and any other singular field has presence.prutalgen writes the same markers, plus its own implicit marker
for an edition 2023 field with features.field_presence = IMPLICIT,
which protoc-gen-go leaves unmarked.prutalgen versions carries no markers and is read as having presence:
a bytes field without presence, proto3 or editions implicit,
holding an empty non-nil slice is serialized as an empty field instead of being skipped.
Decoders read it as the default value; regenerate to get the exact output.protoc-gen-go output for an edition 2023 implicit bytes field has the same divergence,
as the runtime cannot tell it from a field with presence.protojson equivalentprototext)protoreflect)protoregistry)dynamicpb)protobuf-go are dropped by Marshal; on Unmarshal they are kept as unknown fields and written back as suchprutalgen)google.golang.org/protobuf/types/known, Any is limitedUse pkg/grpccodec and pass grpccodec.PrutalCodec to the gRPC v1 codec APIs on both server and client.
See pkg/grpccodec/README.md for usage details and tests/cases/grpc for a complete example.
Contributor guide: Contributing.
Prutal is licensed under the terms of the Apache license 2.0. See LICENSE for more information.
Dependencies used by prutal are listed under licenses.
232 followers · starred Oct 2025
25 followers · starred Apr 2025
37 followers · starred Feb 2025
3 followers · starred Oct 2025