kotlinx.rpc 0.10.2 Help

Known limitations

The gRPC integration is under active development. This page lists current limitations that may affect your project.

Platform support

The following Kotlin targets are not supported:

  • Kotlin/JS

  • Kotlin/Wasm (both WasmJs and WasmWasi)

gRPC support is available for JVM, Android, Apple, and Linux targets. See Platforms for the full per-artifact matrix.

Protobuf code generation

Field presence API is being redesigned

The way optional fields map to Kotlin types is being reworked. Currently, optional fields are generated with their default values and a has<Field>() presence API. A future release will introduce Kotlin nullable types for optional fields, with extension properties like fieldOrDefault to access default values when presence is not set. The exact API shape — including whether to default to nullable or non-nullable types, and how editions 2023+ (where all fields are implicitly optional) interact with this — is still under discussion.

Well-Known Types are not mapped to Kotlin types

Well-Known Types such as google.protobuf.Timestamp, google.protobuf.Duration, and google.protobuf.Empty are generated as regular protobuf messages. They are not mapped to Kotlin equivalents like kotlinx.datetime.Instant, kotlin.time.Duration, or Unit.

Oneof field access is being redesigned

oneof fields are generated as Kotlin sealed classes and accessed through a wrapper property (e.g. message.either.success). A flatter access pattern (e.g. message.success) and a more ergonomic builder syntax are being explored, while preserving exhaustive when matching as the primary usage pattern.

No kotlin_package option

The kotlin_package file option is not supported. Generated code uses the package derived from the proto package declaration.

No kotlin_multiple_files option

The kotlin_multiple_files file option is not supported. All declarations from a single .proto file are generated into a single Kotlin file.

Decoded lists and maps are mutable

List and map fields in decoded messages are backed by mutable collections. Modifying them after decoding may lead to unexpected behavior.

No message merging

There is no mergeFrom equivalent. To combine two messages, you must manually copy fields using the builder DSL.

No runtime access to field numbers

Proto field numbers are not exposed in the generated Kotlin API. If you need to work with raw field numbers at runtime, you must maintain the mapping manually.

No descriptor-based reflection

Unlike protobuf-java, there is no runtime reflection API based on descriptors. Features like Descriptors.Descriptor, Descriptors.FieldDescriptor, dynamic field access via getField/setField, and DynamicMessage are not available. Generic proto processing, schema-driven validation, and dynamic message routing must be implemented using the generated static API.

No JSON encoding for protobuf messages

Protobuf messages can only be serialized in the binary wire format. JSON encoding (as specified by the proto3 JSON mapping) is not available.

Unknown fields are not accessible

Unknown fields encountered during decoding are preserved and re-encoded, but there is no API to read or write them directly.

gRPC runtime

No per-service or per-method interceptors

Client and server interceptors can only be applied globally. There is no way to attach an interceptor to a specific service or method.

No per-service call options

GrpcCallOptions (such as deadlines and credentials) can only be set at the client level. Per-service configuration via withService is not available.

No gRPC transcoding

REST-to-gRPC transcoding (as defined by google.api.http annotations) is not supported.

Java interoperability

No compatibility with protobuf-java generated types

Generated Kotlin protobuf types are not compatible with protobuf-java or grpc-java generated types. If your project depends on Java libraries that accept or return protobuf-java Message instances, you cannot pass kotlinx.rpc-generated messages directly. Interop requires serializing to bytes on one side and deserializing on the other.

Calling generated code from Java may be inconvenient

The generated API is designed to be Kotlin-first. Kotlin-specific constructs such as extension properties, builder DSLs, and default parameter values may not translate well when called from Java. If your project has Java callers that need to work with generated protobuf types, you may need to write Kotlin wrapper functions to provide a Java-friendly API.

Gradle plugin

Eager configuration in Gradle 9.0

The plugin eagerly resolves jar dependencies for the Buf CLI and protoc plugins, which triggers a configuration-time warning in Gradle 9.0 and later. The build still succeeds, but the warning may appear in your console output.

Last modified: 10 March 2026