A code generator that produces plain Go structs from .proto files. No protoc dependency, no protobuf runtime — generated code is ordinary Go structs that work directly with GORM, JSON serialization, and gin HTTP services.
Why gcode? Official protoc-gen-go generates structs containing runtime fields (protoimpl.MessageState, sizeCache, unknownFields) that are not suitable as DAO layer data structures and forces a dependency on google.golang.org/protobuf runtime. gcode produces plain Go structs with zero runtime dependencies — usable directly with GORM, JSON serialization, and gin HTTP binding, while maintaining full wire format compatibility with the official protobuf binary format.
- No protoc required — Parses proto files in pure Go via
protocompile.go installand you're done. - Wire format compatible — Generated
MarshalBinary/UnmarshalBinaryis fully compatible with the official protobuf binary format. - JSON tags built-in — Generates
json:"camelCase"tags by default; supportsomitempty/ignorevia annotations. - GORM support — Generates gorm struct tags and
TableName()via(gcode.message).gormannotation. - Built-in validation — Reuses
buf/validateannotation syntax to generateValidate() errormethods. - Derived message generation — Declare update/create derived messages via annotations in
.meta.protoschema files;gen-protogenerates entity/create/update proto files with validate annotations explicitly copied. - gin HTTP adapter — Generates handler factory functions decoupled from service interfaces.
- TypeScript generation — Generates interfaces, enums, and validation metadata from proto files via
gcode gen-ts. - Comment passthrough — Proto leading comments pass through to all generated code.
go install github.com/pinealctx/gcode/cmd/gcode@latestVerify:
gcode -hCreate a new Go module and proto directory:
mkdir myapp && cd myapp
go mod init myapp
mkdir proto dao1. Write a proto file
// proto/user.proto
syntax = "proto3";
package myapp;
// go_package determines the Go package name for generated code:
// "import/path;pkg" — the part after ';' is the Go package name.
// The import path is used by gcode for package resolution.
// The -out flag controls where files are written to disk.
option go_package = "myapp/dao;dao";
message User {
string name = 1;
int32 age = 2;
}2. Generate code
gcode -in proto/ -out dao/3. Install runtime dependencies
Generated code imports packages from the gcode module:
go get github.com/pinealctx/gcode/runtimeOnly
runtimeis needed for basic struct generation. If you usebuf/validateannotations, addgo get github.com/pinealctx/gcode/validateruntime. If you useservicedefinitions with gin handlers, addgo get github.com/gin-gonic/ginandgo get github.com/pinealctx/gcode/httpruntime.Note: Running
go buildbeforego getwill produce a missing module error — that is expected. Rungo getfirst, then build.
4. Use the generated struct
package main
import (
"fmt"
"log"
"myapp/dao"
)
func main() {
u := &dao.User{Name: "Alice", Age: 30}
// Serialize to protobuf wire format
wire, err := u.MarshalBinary()
if err != nil {
log.Fatal(err)
}
// Deserialize
var u2 dao.User
if err := u2.UnmarshalBinary(wire); err != nil {
log.Fatal(err)
}
fmt.Println(u2.Name, u2.Age)
}Derived messages: If you use
gcode.update_messageorgcode.create_messageannotations, write them in a.meta.protoschema file withoption (gcode.schema) = {}. Then rungcode gen-proto -in proto/to generate*.entity.proto,*.create.proto, and*.update.proto, thengcode -in proto/ -out dao/. See Getting Started for the full workflow.
5. Generate TypeScript types (optional)
If you need frontend type definitions:
gcode gen-ts -in proto/ -out ts/This generates .pb.ts files with TypeScript interfaces, enums, and validation metadata. See Getting Started — TypeScript Generation for details.
| Document | Description |
|---|---|
| Getting Started | Full 8-step example (proto to HTTP service), annotation quick reference |
| Architecture | Pipeline overview, layer responsibilities, directory structure |
| Annotations Reference | Detailed documentation and examples for all annotations |
| Design Decisions | Key architectural decisions (ADR style, D1–D15) |
| Limitation | Details |
|---|---|
| No streaming RPC | Exits with error when stream keyword is encountered |
| No path params | HTTP handlers use c.ShouldBindJSON uniformly; URL path parameters not supported |
No map, oneof, well-known types |
Proto files using these features may produce incorrect code |
| Flat Go output directory | Go generation writes all generated Go files into one output package directory. Proto files with the same basename are not supported in one generation run, even when they are in different source subdirectories. |
| Cross-package references untested | Same-package cross-file works; cross-package not fully tested |
| proto3 only | proto2 syntax is not supported |
See CONTRIBUTING.md for development setup, code style, and PR guidelines.
See CHANGELOG.md for release history.