kotlinx.rpc 0.10.2 Help

Configuration

The gRPC integration is schema-first: you define your services in .proto files, and the Gradle plugin generates the Kotlin code for you. Under the hood, the plugin uses the Buf CLI to manage the protoc workspace and run code generation.

Repositories

Both plugin resolution and dependency resolution must include the gRPC dev repository.

settings.gradle.kts:

pluginManagement { repositories { gradlePluginPortal() mavenCentral() maven("https://redirector.kotlinlang.org/maven/kxrpc-grpc") } } dependencyResolutionManagement { repositories { mavenCentral() maven("https://redirector.kotlinlang.org/maven/kxrpc-grpc") } }

Simple setups

This layout keeps schemas, client code, and server code in the same JVM module.

plugins { kotlin("jvm") version "2.3.0" id("org.jetbrains.kotlinx.rpc.plugin") version "<version>" } repositories { mavenCentral() maven("https://redirector.kotlinlang.org/maven/kxrpc-grpc") } dependencies { implementation("org.jetbrains.kotlinx:kotlinx-rpc-grpc-core:<version>") implementation("org.jetbrains.kotlinx:kotlinx-rpc-protobuf-core:<version>") implementation("org.jetbrains.kotlinx:kotlinx-rpc-grpc-client:<version>") implementation("org.jetbrains.kotlinx:kotlinx-rpc-grpc-server:<version>") implementation("io.grpc:grpc-netty:<grpc-java-version>") } rpc { protoc() }

The default schema directories are src/main/proto and src/test/proto. If the module only owns schemas, the client/server runtime dependencies can be moved to consumer modules.

This layout keeps generated messages and service interfaces in a shared module. Platform-specific modules add runtime dependencies where clients or servers are instantiated.

plugins { kotlin("multiplatform") version "2.3.0" id("org.jetbrains.kotlinx.rpc.plugin") version "<version>" } kotlin { jvm() iosArm64() iosSimulatorArm64() sourceSets { commonMain.dependencies { api("org.jetbrains.kotlinx:kotlinx-rpc-grpc-core:<version>") api("org.jetbrains.kotlinx:kotlinx-rpc-protobuf-core:<version>") } jvmMain.dependencies { implementation("org.jetbrains.kotlinx:kotlinx-rpc-grpc-client:<version>") implementation("org.jetbrains.kotlinx:kotlinx-rpc-grpc-server:<version>") implementation("io.grpc:grpc-netty:<grpc-java-version>") } } } rpc { protoc() }

The default shared schema directory is src/commonMain/proto. Additional source sets such as jvmMain, nativeMain, or androidMain can also own .proto files.

Android source sets are supported by the Gradle plugin, including AGP 9.x projects that use the built-in Kotlin support.

plugins { id("com.android.application") version "<agp-version>" kotlin("android") version "2.3.0" id("org.jetbrains.kotlinx.rpc.plugin") version "<version>" } android { namespace = "com.example.app" compileSdk = 34 } dependencies { implementation("org.jetbrains.kotlinx:kotlinx-rpc-grpc-core:<version>") implementation("org.jetbrains.kotlinx:kotlinx-rpc-protobuf-core:<version>") } rpc { protoc() }

The default schema directory is src/main/proto. Variant-specific directories such as src/debug/proto, src/release/proto, src/androidTest/proto, or src/testFixtures/proto are also supported when those source sets exist.

Here <version> comes from here:

Latest dev version

Source sets and tasks

Once protoc() is enabled, the plugin creates matching proto source sets, a generated Buf workspace, and code generation tasks.

  • Every Kotlin/JVM source set, Kotlin Multiplatform source set, and supported Android source set gets a matching proto source set with the default directory src/<sourceSet>/proto.

  • KMP hierarchy source sets are supported. For example, commonMain, jvmMain, nativeMain, appleMain, macosMain, and Android KMP source sets all participate in the proto graph when present.

  • Test-like source sets automatically import the corresponding main source set. Additional import graphs can be configured explicitly.

For each proto source set, the following tasks are generated:

  • generateBufYaml<SourceSet> — writes buf.yaml.

  • generateBufGenYaml<SourceSet> — writes buf.gen.yaml.

  • process<SourceSet>ProtoFiles — copies the source set's own .proto files.

  • process<SourceSet>ProtoFilesImports — copies imported .proto files.

  • bufGenerate<SourceSet> — runs buf generate for the prepared workspace.

The generated workspace lives in build/protoBuild/sourceSets/<sourceSet>. Generated Kotlin sources are written into build/protoBuild/generated/<sourceSet>/kotlin-multiplatform and build/protoBuild/generated/<sourceSet>/grpc-kotlin-multiplatform. Outputs from additional protoc plugins are written to sibling directories named after the plugin.

Supported platforms

The gRPC integration supports the following platforms:

  • JVM

  • Android

  • Apple

  • Linux

The full per-artifact matrix is listed on Platforms.

Protoc plugins

Every proto source set gets two built-in protoc plugins by default:

  • kotlin-multiplatform — generates public protobuf declarations and internal protobuf support code.

  • grpc-kotlin-multiplatform — generates public @Grpc service interfaces.

Additional local or remote plugins can be registered in rpc.protoc.plugins and attached selectively per proto source set:

import kotlinx.rpc.protoc.* rpc { protoc { plugins { create("myPlugin") { local { executor("path", "to", "protoc-gen-myplugin.exe") } options.put("hello", "world") strategy.set(ProtocPlugin.Strategy.All) includeImports.set(true) includeWkt.set(false) types = listOf("my.type.Yay") excludeTypes = listOf("my.type.Nope") } create("myRemotePlugin") { remote { locator = "my.remote.plugin" } options.put("hello", "world") } } } } kotlin.sourceSets { main.proto { plugin { getByName("myPlugin") } plugin({ options.put("only", "in main") }) { getByName("myRemotePlugin") } } test.proto { plugin({ options.put("only", "in test") }) { getByName("myRemotePlugin") } } }

ProtocPlugin capabilities:

isJava

Marks the plugin output as Java sources and wires the output directory into Java compilation.

isKotlin

Marks the plugin output as Kotlin sources and wires the output directory into Kotlin compilation.

options

Adds plugin-specific opt entries to buf.gen.yaml.

local

Configures a local plugin executable with executor(...) or javaJar(...). Local plugins can also declare executableFiles for Gradle task caching.

remote

Configures a remote Buf Schema Registry plugin using locator.

strategy

Buf generation strategy: Directory (splits input by directory, default for local plugins) or All (single invocation with all files, default for remote plugins).

includeImports

Also generate all imports except for Well-Known Types.

includeWkt

Also generate Well-Known Types. Requires includeImports to be set to true.

types

Restricts generation to specific fully qualified protobuf types.

excludeTypes

Excludes specific fully qualified protobuf types from generation.

The built-in plugins are exposed as plugins.kotlinMultiplatform and plugins.grpcKotlinMultiplatform.

Proto source sets

Proto source sets can be configured either through the project-level protoSourceSets container or through source-set-specific extensions such as kotlin.sourceSets.commonMain.proto { ... }.

import kotlinx.rpc.protoc.* kotlin.sourceSets { commonMain.proto { include("public.proto") exclude("internal.proto") fileImports.from(layout.projectDirectory.file("schemas/health.proto")) plugin({ options.put("mode", "lite") }) { getByName("myPlugin") } } }

ProtoSourceSet capabilities:

include / exclude

Filter the .proto files that belong to the source set.

plugin(...)

Attaches a registered protoc plugin to the source set and optionally overrides its options just for that source set.

importsFrom / importsAllFrom

Makes proto files available as imports without generating code from them.

fileImports

Adds standalone imported proto files that do not belong to another proto source set.

extendsFrom

Reuses another proto source set as generation input and inherits its imports and plugins.

Buf

kotlinx.rpc uses the Buf CLI to prepare the workspace and run generation. Buf configuration lives under rpc.protoc.buf.

import kotlinx.rpc.buf.* import kotlin.time.Duration.Companion.seconds import java.io.File rpc { protoc { buf { configFile = File("some.buf.yaml") logFormat = BufExtension.LogFormat.Json timeout = 60.seconds generate { includeImports = true includeWkt = true errorFormat = BufGenerateExtension.ErrorFormat.Json indentSize = 4 comments { copyComments = true includeFileLevelComments = true } } } } }

BufExtension capabilities:

configFile

Passes --config to Buf — a path to a custom buf.yaml file.

logFormat

Passes --log-format. Supported values are Text, Color, and Json.

timeout

Passes --timeout. Duration is converted to whole seconds. Setting it to zero means no timeout.

generate.includeImports

Passes --include-imports — also generates all imports except for Well-Known Types.

generate.includeWkt

Passes --include-wkt — also generates Well-Known Types. Cannot be set without includeImports.

generate.errorFormat

Passes --error-format. Supported values are Text, Json, Msvs, Junit, and GithubActions.

generate.indentSize

Controls the indentation size used by the built-in Kotlin generators. This is a kotlinx.rpc-specific option, not a Buf flag.

generate.comments.copyComments

Controls whether comments from the original .proto files are copied to generated Kotlin sources. This is a kotlinx.rpc-specific option, not a Buf flag.

generate.comments.includeFileLevelComments

Controls whether file-level comments are copied to generated Kotlin sources. This is a kotlinx.rpc-specific option, not a Buf flag.

Custom Buf tasks

Custom Buf tasks can be registered on top of the generated workspace. The most convenient entry point is rpc.protoc.buf.tasks.registerWorkspaceTask:

import kotlinx.rpc.buf.tasks.* import kotlinx.rpc.protoc.ProtoTask import javax.inject.Inject abstract class BufLintTask @Inject constructor( properties: ProtoTask.Properties, ) : BufExecTask(properties) { init { command.set("lint") args.set(emptyList()) } } rpc { protoc { buf { tasks { registerWorkspaceTask<BufLintTask>("lint") } } } }

If you need a plain Gradle task that only reuses the configured Buf executable and global Buf options, use Project.registerBufExecTask(...) instead.

Last modified: 10 March 2026