Protobuf to Kotlin Converter
Paste a .proto schema. Get Kotlin data classes with proper types, camelCase fields, and default values.
Input (.proto schema)
Output (Kotlin)
What this tool does
You have a Protocol Buffers schema — maybe from a backend team, maybe from a third-party API contract — and a Kotlin codebase that needs typed shapes for it. Either an Android app calling a gRPC backend, or server-side Kotlin parsing JSON-encoded Protobuf messages. Setting up the full grpc-kotlin codegen pipeline is overkill if you only need the data class shapes — paste, copy, drop in.
Type mapping follows Kotlin idioms: string → String, bool → Boolean, bytes → ByteArray, int32/sint32/fixed32 → Int, int64/sint64/fixed64 → Long, double → Double, float → Float. repeated T becomes List<T> with default emptyList(); map<K, V> becomes Map<K, V> with default emptyMap(). Singular nested message fields are nullable (?) with default null — matches proto3 has-value semantics.
Field names convert from snake_case in the proto to camelCase in Kotlin (order_id → orderId) — the standard Kotlin coding convention per official Kotlin style. Class and enum names stay PascalCase. Each enum becomes an enum class with an Int backing value. Conversion runs entirely in your browser — your .proto never leaves the page.
How to use it
Three steps. Output is paste-ready Kotlin.
Paste your .proto schema
Drop the schema into the left editor. syntax = "proto3"; at the top is fine but optional. Nested message blocks, enum declarations, oneof, map<K, V>, and field options are all handled.
Kotlin code conventions favour camelCase for properties — the converter does that for you. If you prefer the original snake_case names (some serialisation libraries match field names exactly), find-replace in the output.
Read the Kotlin output
On the right: each message becomes a data class with default values for every property. Each enum becomes an enum class(val value: Int) so you can round-trip the wire format. Top-level only (no nesting) — easy to drop into one file or split.
Wire it into your project
Drop the file into your project, add a package declaration, and import. For real gRPC code on Android or the JVM you will still want to run grpc-kotlin codegen so you get the marshal methods and stubs. This output is for typed JSON handling, struct sketches, and reviews.
When this actually saves time
Sketching Android types from a backend .proto
Your Android app talks to a gRPC backend. The backend team owns the .proto. You want the data class shapes for typing your view models without setting up codegen yet. Paste, drop into Models.kt, you are typed.
Server-side Kotlin parsing JSON-encoded Protobuf
Your server-side Kotlin (Ktor / Spring Boot) consumes JSON that follows the proto3 JSON encoding. You need data classes that match. Paste the .proto, copy the Kotlin output, plug it into your serialiser of choice.
Reviewing a Protobuf API change
A teammate added fields to a message. Paste the new .proto, diff the Kotlin output against your current Models.kt, leave a focused review without spinning up the full toolchain.
One-off scripts and quick prototypes
A 50-line Kotlin script that hits a gRPC-gateway. Setting up grpc-kotlin and protoc just for that is overkill. Generate the data classes here, drop them in.
Common questions
Is this a replacement for protoc-gen-kotlin?
No. Real codegen produces marshal/unmarshal methods, descriptors, and the gRPC stubs. This tool only emits the data class shapes. Run grpc-kotlin for production gRPC code. Use this for sketches, JSON parsing, reviews, and one-off scripts.
Why are singular message fields nullable?
In proto3, message fields have a "has value" semantic — they can be unset. The cleanest Kotlin equivalent is a nullable property with default null. If you know your data always populates these fields, drop the ? and the default — straightforward find-replace.
How are uint32 and uint64 handled?
Both map to signed types (Int and Long). Kotlin has stable UInt and ULong types since 1.5, but signed types are more compatible with existing serialisation libraries and most Android codebases. If you specifically need the unsigned variants, swap them in the output.
How are enums emitted?
Each becomes an enum class WithValue(val value: Int) so you can preserve the wire-format integer. Each value gets the original proto name (e.g. ORDER_STATUS_PENDING) — Kotlin enum entries are conventionally SCREAMING_SNAKE_CASE already, so this matches.
How are field names converted?
snake_case → camelCase per Kotlin coding conventions. order_id becomes orderId, customer_name becomes customerName. Class and enum names stay PascalCase as in the proto.
Does it handle nested messages?
Yes — nested message blocks are flattened to top-level data class declarations in the output. That keeps the file easy to read and split into multiple files. If you prefer Kotlin nested classes, wrap them by hand.
Related tools
If you are working with Protobuf and Kotlin, these pair well: