#1414·protobuf

protojson: Add MarshalOption to write int64 as a number and not as a string

Author: corgrathCreated Feb 17, 2022Updated Oct 13, 2025

Is your feature request related to a problem? Please describe. When using the protonjson library int64 numbers are outputted as strings in the JSON due to this code:

https://github.com/protocolbuffers/protobuf-go/blob/b92717ecb630d4a4824b372bf98c729d87311a4d/encoding/protojson/encode.go#L275-L278

From what I understand, it is written as a string since JavaScript cannot handle that precision.

However, from a JSON stand point (not JavaScript), it should handle any integers (JSON should not care about precision, just as XML shouldn't care about precision).

We are only interested in marshaling a message to a JSON, not to JavaScript, so would like the protonjson to write int64 as an integer/number and not as a string.

Describe the solution you'd like Add a new to option to MarshalOptions :

https://github.com/protocolbuffers/protobuf-go/blob/b92717ecb630d4a4824b372bf98c729d87311a4d/encoding/protojson/encode.go#L43

Something like:

	// Write64KindsAsInteger will write any 64 bit kinds as integers instead of a string.
	Write64KindsAsInteger

And then in marshalSingular use this option:

	case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
		if e.opts.Write64KindsAsInteger {
			e.WriteInt64(val.Int())
		} else {
			// 64-bit integers are written out as JSON string.
			e.WriteString(val.String())
		}

	case pref.Uint64Kind, pref.Fixed64Kind:
		if e.opts.Write64KindsAsInteger {
			e.WriteUInt64(val.Int())
		} else {
			// 64-bit integers are written out as JSON string.
			e.WriteString(val.String())
		}

Describe alternatives you've considered AFAK, there are no other feasible solutions to write int64s as integers in the JSON output.

Additional context If you use the default JSON marshaller (encoding/json), int64 is written as a number.

However, since we need to output default values, we are forced to use this library due to the EmitUnpopulated option.

So right now our organization is between a hard rock and a stone; Either omit default values (such as 0 and false) or write int64 as strings (and breaking other tools that reads in JSON data).