puregen is a protobuf plugin that generates simple, dependency-minimal code for Go, Java, and Python from .proto
files. The generated code focuses on simplicity and uses built-in language features rather than heavy dependencies.
puregen is ideal for projects that need simple, readable generated code without heavy protobuf runtime dependencies, with the flexibility to use any transport mechanism (HTTP, gRPC, message queues, etc.).
Feature | puregen | protoc-gen-go | protoc-gen-java |
---|---|---|---|
Dependencies | Minimal | protobuf runtime | protobuf runtime |
Code size | Small | Large | Large |
JSON support | Built-in | Requires jsonpb | Requires additional libs |
Transport abstraction | Pluggable | gRPC only | gRPC only |
Customization | Easy | Complex | Complex |
Learning curve | Low | Medium | Medium |
- Multi-language support: Generate code for Go, Java, and Python
- Minimal dependencies: Uses only built-in libraries and standard patterns
- Simple data structures: Generated classes/structs are easy to understand and modify
- JSON serialization: Built-in JSON marshaling/unmarshaling support
- Service interfaces: Clean interface definitions for RPC services
- Comprehensive directive support: Customize code generation with
puregen:generate
andpuregen:metadata
directives for default values, enum types, HTTP routing, database mapping, validation, UI configuration, etc. See details - Client generation: Ready-to-use clients with pluggable transport. See details
- Protocol Buffers compiler (
protoc
). Install it from the official site.
You can download pre-built binaries for your platform from the releases page.
curl -L https://github.com/nnanto/puregen/releases/download/latest/protoc-gen-puregen-linux-amd64.tar.gz | tar -xz
sudo mv protoc-gen-puregen-* /usr/local/bin/protoc-gen-puregen
# Or for macOS
curl -L https://github.com/nnanto/puregen/releases/download/latest/protoc-gen-puregen-darwin-amd64.tar.gz | tar -xz
sudo mv protoc-gen-puregen-* /usr/local/bin/protoc-gen-puregen
# Run the generator
protoc --puregen_out=./examples/generated --puregen_opt=language=python examples/proto/*.proto
# Clone the repository
git clone https://github.com/nnanto/puregen
cd puregen
# Build the plugin
go build -o protoc-gen-puregen ./cmd/protoc-gen-puregen
# Make it available in your PATH (optional)
sudo mv protoc-gen-puregen /usr/local/bin/
Generate code for all supported languages:
protoc --puregen_out=./generated --puregen_opt=language=all user.proto
Generate code for a specific language:
# Go only
protoc --puregen_out=./generated --puregen_opt=language=go user.proto
# Java only
protoc --puregen_out=./generated --puregen_opt=language=java user.proto
# Python only
protoc --puregen_out=./generated --puregen_opt=language=python user.proto
syntax = "proto3";
package example.v1;
option go_package = "github.com/nnanto/puregen/examples/proto/gen/go";
option java_package = "com.example.proto.v1";
// User represents a user in the system
// puregen:metadata: {"table": "users", "cache": "true"}
message User {
int32 id = 1;
// puregen:generate: {"value": "Anonymous"}
string name = 2;
string email = 3;
// Default to active status
// puregen:generate: {"value": "true"}
bool is_active = 4;
UserProfile profile = 5;
UserStatus status = 6;
}
// UserProfile contains additional user information
message UserProfile {
// Default bio for new users
// puregen:generate: {"value": "No bio provided"}
string bio = 1;
string avatar_url = 2;
int64 created_at = 3;
}
// Status enum with integer generation
// puregen:generate: {"enumType": "int"}
// puregen:metadata: {"validation": "required", "default": "ACTIVE"}
enum UserStatus {
USER_STATUS_UNKNOWN = 0;
USER_STATUS_ACTIVE = 1;
USER_STATUS_INACTIVE = 2;
}
// CreateUserRequest is the request message for creating a user
message CreateUserRequest {
string name = 1;
string email = 2;
UserProfile profile = 3;
}
message CreateUserResponse {
User user = 1;
string message = 2;
}
message GetUserRequest {
int32 id = 1;
}
message GetUserResponse {
User user = 1;
}
service UserService {
// CreateUser creates a new user
// puregen:metadata {"method":"POST", "path":"/users"}
rpc CreateUser(CreateUserRequest) returns (CreateUserResponse);
// GetUser retrieves a user by ID
// puregen:metadata {"method":"GET", "path":"/users/{id}"}
rpc GetUser(GetUserRequest) returns (GetUserResponse);
}
Simple data structures with validation and serialization
- Go Models Example - Creating and working with generated Go structs
- Java Models Example - Using generated Java classes with builder pattern
- Python Models Example - Working with generated Python dataclasses
Service implementations with HTTP endpoints
- Go Server Example - HTTP server implementation with generated service interface
- Java Server Example - Java HTTP server using generated service classes
- Python Server Example - Flask-based server with generated service interface
Client libraries with pluggable transport
- Go Client Example - HTTP client with custom transport implementation
- Java Client Example - Java HTTP client with transport abstraction
- Python Client Example - Python client with requests-based transport
You can define custom transports for different protocols (HTTP, gRPC, etc.) by implementing the Transport
interface in each language.
Example: Name-Based Routing Transport
- Struct definitions with JSON tags
- Constructor functions (
NewMessageName()
) - Validation methods
- JSON serialization (
ToJSON()
,FromJSON()
) - Service interfaces with default implementations
- Clients with pluggable Transport interface
- POJO classes with Jackson annotations
- Builder pattern support
- Getters and setters
- JSON serialization methods
- Service interfaces with default implementations
- Clients with generic Transport interface
- Dataclasses with type hints
- JSON serialization support
- Validation methods
- Service abstract base classes
- Clients with abstract Transport base class
Test with the provided example:
# Generate code for the example proto file
cd examples
protoc --puregen_out=./generated --puregen_opt=language=all proto/user.proto
# Check the generated files
ls -la generated/
├── cmd/protoc-gen-puregen/ # Main plugin entry point
├── internal/generator/ # Code generation logic
│ ├── go.go # Go code generator
│ ├── java.go # Java code generator
│ └── python.go # Python code generator
├── examples/ # Example proto files and usage
└── README.md
- Create a new generator file in
internal/generator/
- Implement the
GenerateXXXFile
function - Add the language option to the main plugin
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Submit a pull request
MIT License - see LICENSE file for details.