Skip to content

Go Language Support

✅ Full Support 8+ Plugins High Performance

Go support includes the complete Protocol Buffer ecosystem with all major plugins and performance optimizations. Perfect for microservices, CLI tools, and high-performance backend systems.

gRPC Services

Full gRPC server and client code generation with streaming support

HTTP/JSON APIs

REST API gateways via grpc-gateway or modern Connect protocol

High Performance

3.8x faster serialization with vtprotobuf optimization

Validation

Built-in message validation with CEL expressions

Essential Protocol Buffer Support

PluginDescriptionGenerated FilesStatus
protoc-gen-goBase message generation*.pb.go✅ Stable
protoc-gen-go-grpcgRPC services*_grpc.pb.go✅ Stable
protoc-gen-connect-goConnect protocol*_connect.go✅ Modern
protoc-gen-grpc-gatewayHTTP/JSON gateway*.pb.gw.go✅ Popular
Basic Go configuration
languages.go = {
enable = true;
outputPath = "gen/go";
packagePrefix = "github.com/myorg/myproject";
options = [
"paths=source_relative"
"require_unimplemented_servers=false"
];
};
  • Directoryproject/
    • Directoryproto/
      • Directoryuser/
        • Directoryv1/
          • user.proto
    • Directorygen/
      • Directorygo/
        • Directoryuser/
          • Directoryv1/
            • user.pb.go
            • user_grpc.pb.go
languages.go = {
enable = true;
outputPath = "gen/go";
packagePrefix = "github.com/myorg/myproject";
options = ["paths=source_relative"];
# gRPC service generation
grpc = {
enable = true;
options = [
"paths=source_relative"
"require_unimplemented_servers=false"
];
};
# HTTP/JSON gateway for REST APIs
gateway = {
enable = true;
options = [
"paths=source_relative"
"generate_unbound_methods=true"
"allow_delete_body=true"
];
};
# Modern validation (recommended)
protovalidate = {
enable = true;
};
# Legacy validation
validate = {
enable = true;
options = ["lang=go"];
};
# Modern Connect protocol
connect = {
enable = true;
options = ["paths=source_relative"];
};
# High-performance serialization
vtprotobuf = {
enable = true;
options = [
"paths=source_relative"
"features=marshal+unmarshal+size+pool"
];
};
# JSON integration
json = {
enable = true;
options = ["paths=source_relative" "orig_name=true"];
};
# OpenAPI documentation
openapiv2 = {
enable = true;
options = ["logtostderr=true"];
};
# gRPC Federation (experimental)
federation = {
enable = true;
options = ["paths=source_relative"];
};
};
🆕 New Feature

Control exactly which proto files Go processes using files and additionalFiles:

Avoid Go Linting Issues

Problem: Go generates linting errors when processing Google API annotations. Solution: Use files to exclude annotation files from Go while keeping them for other languages.

Smart file separation
# Global files (used by all languages by default)
protoc.files = [
"./proto/common/v1/types.proto"
"./proto/common/v1/status.proto"
];
languages = {
# Go: Override global files - exclude Google annotations
go = {
enable = true;
files = [
"./proto/common/v1/types.proto"
"./proto/common/v1/status.proto"
"./proto/internal/v1/user_service.proto"
# NOTE: No Google API annotations - prevents linting errors
];
grpc.enable = true;
};
# JavaScript: Extend global files - include Google annotations
js = {
enable = true;
additionalFiles = [
"./proto/api/v1/user_api.proto"
"./proto/google/api/annotations.proto" # Needed for REST mapping
"./proto/google/api/http.proto"
];
es.enable = true;
};
};
OptionTypeDescriptionExample
fileslistOverride global files completelyBackend-only services
additionalFileslistExtend global filesAdd monitoring protos

Exclude Google Annotations

Use files to prevent Go linting errors from Google API annotations

Backend Services Only

Generate only internal gRPC services for Go backends

Add Monitoring

Include Go-specific metrics and health check protos

Multi-Team Projects

Different teams can process different proto subsets

Use Buf registry plugins directly:

languages.go = {
enable = true;
plugins = [
"buf.build/protocolbuffers/go"
"buf.build/grpc/go"
{
plugin = "buf.build/community/planetscale-vtprotobuf";
opt = ["features=marshal+unmarshal+size+pool"];
}
"buf.build/community/mfridman-go-json"
"buf.build/bufbuild/validate-go"
];
};
proto/user/v1/user.proto
syntax = "proto3";
package user.v1;
option go_package = "github.com/myorg/myproject/gen/go/user/v1;userv1";
import "validate/validate.proto";
import "google/api/annotations.proto";
message User {
string id = 1;
string name = 2 [(validate.rules).string = {min_len: 1, max_len: 100}];
string email = 3 [(validate.rules).string.email = true];
int32 age = 4 [(validate.rules).int32 = {gte: 0, lte: 150}];
repeated string roles = 5;
UserStatus status = 6;
repeated Address addresses = 7;
message Address {
string street = 1;
string city = 2;
string state = 3;
string zip = 4;
string country = 5;
}
}
enum UserStatus {
USER_STATUS_UNSPECIFIED = 0;
USER_STATUS_ACTIVE = 1;
USER_STATUS_INACTIVE = 2;
USER_STATUS_SUSPENDED = 3;
}
service UserService {
rpc CreateUser(CreateUserRequest) returns (CreateUserResponse) {
option (google.api.http) = {
post: "/v1/users"
body: "user"
};
}
rpc GetUser(GetUserRequest) returns (GetUserResponse) {
option (google.api.http) = {
get: "/v1/users/{user_id}"
};
}
}
message CreateUserRequest {
User user = 1;
}
message CreateUserResponse {
User user = 1;
}
message GetUserRequest {
string user_id = 1;
}
message GetUserResponse {
User user = 1;
}
package main
import (
"context"
"log"
"net"
"google.golang.org/grpc"
pb "github.com/myorg/myproject/gen/go/user/v1"
)
type server struct {
pb.UnimplementedUserServiceServer
users map[string]*pb.User
}
func (s *server) CreateUser(ctx context.Context, req *pb.CreateUserRequest) (*pb.CreateUserResponse, error) {
user := req.GetUser()
// Validation happens automatically if validate plugin is enabled
if err := user.Validate(); err != nil {
return nil, err
}
s.users[user.GetId()] = user
return &pb.CreateUserResponse{User: user}, nil
}
func (s *server) GetUser(ctx context.Context, req *pb.GetUserRequest) (*pb.GetUserResponse, error) {
user, exists := s.users[req.GetUserId()]
if !exists {
return nil, status.Error(codes.NotFound, "user not found")
}
return &pb.GetUserResponse{User: user}, nil
}
func main() {
lis, err := net.Listen("tcp", ":50051")
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterUserServiceServer(s, &server{
users: make(map[string]*pb.User),
})
log.Println("Server listening on :50051")
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}

Enable vtprotobuf for 3.8x faster serialization:

languages.go = {
enable = true;
vtprotobuf = {
enable = true;
options = [
"paths=source_relative"
"features=marshal+unmarshal+size+pool"
];
};
};

Usage:

// Fast marshaling
data, err := user.MarshalVT()
// Fast unmarshaling
var user pb.User
err := user.UnmarshalVT(data)
// Object pooling
user := pb.UserFromVTPool()
defer user.ReturnToVTPool()
  1. Use Source-Relative Paths: Always include paths=source_relative for cleaner imports
  2. Enable Validation: Use protovalidate for modern CEL-based validation
  3. Consider Performance: Enable vtprotobuf for high-throughput services
  4. HTTP APIs: Use gRPC-Gateway or Connect for HTTP/JSON APIs
  5. Documentation: Enable OpenAPI generation for REST API documentation
  6. Smart File Management: Use files to exclude Google API annotations and prevent Go linting errors
  7. Separate Concerns: Use per-language files to create clear backend/frontend boundaries
Terminal window
cd examples/simple-flake
nix develop
go run main.go

If you see import errors, ensure your packagePrefix matches your Go module path:

languages.go = {
packagePrefix = "github.com/yourusername/yourproject";
};

Some plugins aren’t yet in nixpkgs. Provide custom packages:

languages.go = {
vtprotobuf.package = pkgs.buildGoModule { ... };
};
{
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
bufrnix = {
url = "github:conneroisu/bufrnix";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = {
nixpkgs,
flake-utils,
bufrnix,
...
}:
flake-utils.lib.eachDefaultSystem (
system: let
pkgs = import nixpkgs {inherit system;};
in {
devShells.default = pkgs.mkShell {
packages = with pkgs; [
go
protobuf
protoc-gen-go
protoc-gen-go-grpc
buf
];
};
packages = {
default = bufrnix.lib.mkBufrnixPackage {
inherit pkgs;
config = {
root = ".";
protoc = {
includeDirectories = ["proto"];
files = ["proto/example/v1/user.proto"];
};
languages = {
go = {
enable = true;
outputPath = "proto/gen/go";
# Per-language file control (new feature)
# files = [
# "./proto/common/v1/types.proto"
# "./proto/internal/v1/user_service.proto"
# # Note: Exclude Google API annotations to prevent Go linting errors
# ];
# additionalFiles = [
# "./proto/monitoring/v1/metrics.proto"
# ];
# gRPC support
grpc.enable = true;
# OpenAPI v2 generation
openapiv2 = {
enable = true;
outputPath = "proto/gen/openapi";
};
# High-performance vtprotobuf plugin
vtprotobuf = {
enable = true;
options = [
"paths=source_relative"
"features=marshal+unmarshal+size+pool"
];
};
# JSON marshaling support
json.enable = true;
};
};
};
};
};
}
);
}