thriftgo is an Apache Thrift IDL compiler written in Go. It generates Go source code from .thrift files and extends the standard compiler with a plugin system for custom code generation.
.thrift definitions, especially in the CloudWeGo ecosystem.The generated Go code depends on the Apache Thrift Go runtime library. Thriftgo targets github.com/apache/thrift v0.13.0 only. Version 0.14.0 introduced breaking changes to core interfaces (TProtocol, TTransport, TProcessor) by adding context.Context parameters, making it incompatible with code generated by thriftgo.
To avoid the Apache Thrift runtime dependency entirely, use no_default_serdes and no_processor together — this generates plain Go structs without Read/Write methods or processor/client code. Alternatively, use thrift_import_path=<path> to redirect the import to a fork or vendored copy.
Prerequisites: Go 1.18 or later. Ensure $GOPATH/bin (default: ~/go/bin) is in your PATH so the installed binary is accessible.
Install via go install (recommended):
go install github.com/cloudwego/thriftgo@latest
Install from source:
go install github.com/cloudwego/thriftgo@latest
Verify installation:
thriftgo --version
Generate Go code from a Thrift IDL file:
thriftgo -g go example.thrift
Output is written to ./gen-go/<namespace>/.
thriftgo [options] <file.thrift>
| Flag | Short | Type | Default | Description |
|---|---|---|---|---|
--version |
bool | false | Print the compiler version and exit. | |
--help |
-h |
bool | false | Print help message and exit. |
--gen |
-g |
string | Target language and options (required). Repeatable for multiple backends. |
Form: language[:key1=val1[,key2[,key3=val3]]].
Available backends: go, fastgo (experimental). |
| --out | -o | string | ./gen-<lang> | Output directory.
Supports {namespace} and {namespaceUnderscore} placeholders. |
| --include | -i | string | | Add a search path for includes. Repeatable. |
| --recurse | -r | bool | false | Recursively generate code for all included files. |
| --plugin | -p | string | | Invoke an external plugin. Repeatable.
Form: plugin[=path][:key1=val1[,...]]. |
| --verbose | -v | bool | false | Output detailed info logs to stderr. |
| --quiet | -q | bool | false | Suppress all warnings and info logs. |
| --check-keywords | | bool | true | Parsed but currently unused.
Intended to warn if identifiers use keywords from common languages. |
| --plugin-time-limit | | duration | 1m | Execution time limit for plugins. 0 means no limit. |
--quiet suppresses all output including warnings. --verbose adds info-level logs. When both are set, --quiet wins.
fastgo backend (experimental)The fastgo backend generates additional k-<file>.go files containing high-performance FastRead, FastWrite, and BLength methods for structs, unions, and exceptions. It runs the standard go backend first and then appends these files.
thriftgo -g fastgo example.thrift
fastgo accepts the same options as the go backend. Do not combine -g go and -g fastgo — fastgo already runs the go backend internally, so using both would produce duplicate files.
-g go:<options>)Options are passed as a comma-separated list after go:. Combine multiple options with commas:
thriftgo -g go:naming_style=golint,gen_setter,template=slim example.thrift
Boolean options accept true, false, or empty (empty means true).
| Option | Default | Description |
|---|---|---|
thrift_import_path=<path> |
Override the thrift runtime import path. |
Default: github.com/apache/thrift/lib/go/thrift. |
| use_package=<path>=<repl> | | Replace an import path. Form: path=replacement. |
| naming_style=<style> | thriftgo | Identifier naming style: golint, apache, or thriftgo. |
| ignore_initialisms | false | Disable spelling correction of initialisms (e.g. URL). |
| package_prefix=<prefix> | | Prepend a package prefix to all generated import paths. |
| template=<name> | | Use an alternative code template: slim or raw_struct. |
| json_enum_as_text | false | Generate MarshalText and UnmarshalText for enum values. |
| enum_marshal | false | Generate MarshalText for enum values. |
| enum_unmarshal | false | Generate UnmarshalText for enum values. |
| gen_setter | false | Generate Set* methods for struct fields. |
| gen_db_tag | false | Generate db:"<fieldname>" struct tags. |
| omitempty_for_optional | true | Generate omitempty JSON tags for optional fields. |
| use_type_alias | true | Generate type aliases for typedef instead of type definitions. |
| validate_set | true | Generate code to validate uniqueness of set elements. |
| value_type_in_container | false | Use value types (not pointers) for struct-like types in containers. |
| scan_value_for_enum | true | Generate Scan and Value methods for enums.
Implements database/sql interfaces. |
| reorder_fields | false | Reorder struct fields to improve memory layout. |
| typed_enum_string | false | Prefix the type name to enum string representations. |
| keep_unknown_fields | false | Generate code to store unrecognized fields in structs. |
| gen_deep_equal | false | Generate DeepEqual for structs, unions, and exceptions.
Silently disabled when template=slim. |
| compatible_names | false | Append _ to names with a New prefix or Args/Result suffix. |
| reserve_comments | false | Preserve comments from the Thrift IDL in generated code. |
| nil_safe | false | Generate nil-safe getter methods. |
| frugal_tag | false | Generate frugal struct tags. |
| unescape_double_quote | true | Unescape double quotes in tag literals. |
| gen_type_meta | false | Generate and register type metadata for structs. |
| gen_json_tag | true | Generate json struct tags. |
| snake_style_json_tag | false | Use snake_case style for JSON tags. |
| lower_camel_style_json_tag | false | Use lowerCamelCase style for JSON tags. |
| with_reflection | false | Generate *-reflection.go files with runtime type metadata for structs.
Required by with_field_mask. |
| enum_as_int_32 | false | Generate enum types as int32. |
| trim_idl | false | Remove unused definitions from the IDL before generating code. |
| json_stringer | false | Use JSON marshaling in the String() method. |
| with_field_mask | false | Generate field-mask support for structs.
Also requires with_reflection. |
| field_mask_halfway | false | Support setting field-mask on non-root structs. |
| field_mask_zero_required | false | Write zero value for required fields filtered by field-mask.
Default: write current value. |
| thrift_streaming | false | Recognize streaming annotations and generate streaming service methods. |
| no_default_serdes | false | Skip generating default Thrift serialization/deserialization code. |
| no_alias_type_reflection_method | false | Skip type reflection methods in *-reflection.go for types annotated with
thrift.is_alias="true". |
| enable_ref_interface | false | Generate interface fields without pointer types for types annotated with
thrift.is_interface="true" in referenced Thrift files. |
| use_option | false | Parse Thrift annotations into struct-style option fields.
Unrecognized keys are silently ignored. |
| streamx | false | Generate streaming interfaces using streamx mode.
Requires thrift_streaming. |
| no_fmt | false | Skip formatting of generated Go code. |
| skip_empty | false | Skip generating files that have no content. |
| no_processor | false | Skip generating the default Thrift processor and client. |
| get_enum_annotation | false | Generate GetAnnotation methods for enum types. |
| apache_warning | false | Call a runtime warning function in Read/Write methods when Apache codec is used. |
| apache_adaptor | false | Replace Read/Write bodies with delegate calls to the Kitex fast codec adaptor.
Uses gopkg/protocol/thrift/apache/adaptor. |
| skip_go_gen | false | Skip Go code generation; only parse the IDL and execute plugins. |
| code_ref | false | Instead of regenerating types, import them from the package path
specified in idl-ref.yaml. |
| code_ref_slim | false | Like code_ref but generates fewer local aliases to reduce import conflicts. |
| exp_code_ref | false | Like code_ref_slim but keeps some structs as local definitions. (experimental) |
| keep_code_ref_name | false | When using code_ref, write the ref file with the same filename
instead of appending -ref.go. |
| enable_nested_struct | false | Generate nested fields when thrift.nested="true" is set on a field.
Requires slim or raw_struct template. |
Explanations for flags that require more context than the table provides.
naming_styleControls how IDL identifiers (struct names, field names, etc.) are converted to Go identifiers. All three styles split on _ and capitalize words, with common initialisms like url, id, http upgraded to uppercase (URL, ID, HTTP) by default.
| Style | Key differences |
|---|---|
thriftgo (default) |
Capitalizes words that start with a lowercase letter; already-uppercase words are left unchanged. Does not append _ to any names. |
golint |
Follows stricter golint-style rules. Preserves leading underscores (_name stays _Name) and underscores between digits (v1_2 → V1_2). |
apache |
Replicates the apache/thrift Go generator. Names ending in Args or Result get an extra _ appended (GetUserArgs → GetUserArgs_). Uppercase words following _ keep an underscore prefix in the output. |
ignore_initialisms disables the initialism correction (user_url → UserUrl instead of UserURL).
compatible_namesthriftgo generates <FuncName>Args and <FuncName>Result structs for every RPC method. If your IDL defines a user struct whose name ends in Args or Result, or starts with New, the names collide. compatible_names appends _ to the user-defined name to resolve this.
# IDL
struct GetUserArgs { 1: string id } # would collide with generated GetUser_args
Without compatible_names: compile error due to duplicate name. With it: GetUserArgs_ is generated instead.
value_type_in_containerBy default, struct-like types inside list, set, or map are generated as pointer types:
// default
type MyStruct struct { Items []*Inner }
With value_type_in_container:
// with value_type_in_container
type MyStruct struct { Items []Inner }
Use this to avoid heap allocations when container elements are small and frequently iterated.
gen_type_metaGenerates an init() block in each file that registers every struct into a global metadata registry:
func init() {
meta.RegisterStruct(NewMyStruct, <serialized-IDL-bytes>)
}
This enables runtime reflection-based construction of structs by name. Used by frameworks that need to instantiate types dynamically without knowing them at compile time.
json_stringerChanges the generated String() method on structs to return a JSON representation instead of Go's default fmt.Sprintf("%+v", p)-style output. Useful when struct values are logged or printed and a JSON format is preferred.
with_reflection, with_field_mask, field_mask_halfway, field_mask_zero_requiredThese four flags work together to enable field-mask support — a mechanism for selectively serializing/deserializing only a subset of struct fields (similar to Protobuf FieldMask).
with_reflection: generates *-reflection.go files containing type descriptors (field names, IDs, types). Required by field-mask for path validation.with_field_mask: adds a _fieldmask *fieldmask.FieldMask field and Set_FieldMask() method to each struct. Read/Write then consult the mask and skip excluded fields.field_mask_halfway: by default a field-mask may only be set on the root (top-level) struct. This option allows setting it on any nested struct. Note: if multiple parent objects share the same child, only one parent's mask will take effect.field_mask_zero_required: required fields that are excluded by a mask are normally still written with their current value. With this option they are written as zero values instead.Minimal usage:
thriftgo -g go:with_field_mask,with_reflection service.thrift
thrift_streaming and streamxTwo flags, two levels of streaming support:
thrift_streaming: without this, any service method with a streaming annotation is silently dropped from the generated output. Enable it to retain and generate streaming methods.streamx: changes the generated streaming interface types to use github.com/cloudwego/kitex/pkg/streaming (the streamx API). Requires thrift_streaming.Use thrift_streaming alone when targeting the default Kitex streaming API. Add streamx when targeting the newer streamx API.
no_default_serdesBy default every struct gets Read(iprot thrift.TProtocol) and Write(oprot thrift.TProtocol) methods containing the full field-by-field serialization logic. With no_default_serdes, those method bodies are replaced with stub insertion points (ExtraFieldMap, ExtraStruct), a
$ claude mcp add thriftgo \
-- python -m otcore.mcp_server <graph>