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.
Feature Comparison
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)
❌
Protobuf Compatibility
✅ Works with code generated by the official Protocol Buffer Go (protoc-gen-go), open API and hybrid API without the protoopaque build tag
❌ Opaque API (default_api_level=API_OPAQUE, or the hybrid API built with -tags protoopaque): field presence lives in a bitmap the runtime does not maintain
Core Message Operations
✅ Marshal / Unmarshal — binary wire format
✅ MarshalAppend — append-friendly encoding
✅ Size — compute wire size without marshaling (zero allocation)
✅ Reset
❌ Clone / Merge / Equal
❌ CheckInitialized — validate required field presence
The presence of a 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.
Code generated by earlier 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.
✅ Map fields
✅ Oneof fields
✅ Required fields (proto2)
✅ Packed / unpacked encoding: written as declared, both forms are accepted on decode
PACKED / EXPANDED (repeated field encoding, edition 2023)
Prutal
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.
Feature Comparison
Protobuf Compatibility
protoc-gen-go), open API and hybrid API without theprotoopaquebuild tagdefault_api_level=API_OPAQUE, or the hybrid API built with-tags protoopaque): field presence lives in a bitmap the runtime does not maintainCore Message Operations
Proto Language Support
allow_alias)bytesfield is read from the struct tag asprotoc-gen-gowrites it: a field of a proto3 file carriesproto3, a proto3 optional fieldoneofon top of it, and any other singular field has presence.prutalgenwrites the same markers, plus its ownimplicitmarker for an edition 2023 field withfeatures.field_presence = IMPLICIT, whichprotoc-gen-goleaves unmarked.prutalgenversions carries no markers and is read as having presence: abytesfield 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-gooutput for an edition 2023 implicitbytesfield has the same divergence, as the runtime cannot tell it from a field with presence.Encoding Formats
protojsonequivalentprototext)Reflection
protoreflect)protoregistry)dynamicpb)Extension Support
protobuf-goare dropped by Marshal; on Unmarshal they are kept as unknown fields and written back as suchCode Generation (
prutalgen)google.golang.org/protobuf/types/known,Anyis limitedHow to use Prutal with gRPC
Use
pkg/grpccodecand passgrpccodec.PrutalCodecto the gRPC v1 codec APIs on both server and client.See
pkg/grpccodec/README.mdfor usage details andtests/cases/grpcfor a complete example.Contributing
Contributor guide: Contributing.
License
Prutal is licensed under the terms of the Apache license 2.0. See LICENSE for more information. Dependencies used by
prutalare listed under licenses.