What Connect-Ktor is, who it is for, and how it relates to Connect-Kotlin.
Connect-Kotlin already gives JVM and Android clients a typed Connect client. Connect-Ktor answers the other half of that sentence: a Ktor server that can accept those calls without abandoning the REST routes already in production.
It is an unofficial community library — useful and conformance-tested, but not a ConnectRPC organization product.
These pages cover the Ktor server side. For Connect itself, Connect-Kotlin clients, or the protocol rules, prefer the official material:
Connect has strong client libraries and a clear protocol story. On the JVM server side, many teams still run Ktor with handwritten JSON REST.
Rewriting that surface as gRPC is often the wrong trade. gRPC wants HTTP/2 end-to-end, a different tooling culture, and a sharper break from browser-friendly APIs.
Connect sits closer to ordinary HTTP. Unary calls look like POST (or GET when idempotent). JSON and binary Protobuf both work. That is why it fits an existing Ktor app: you add handlers, you do not replace the transport stack.
connectJson() / connectProto() ContentNegotiation codecsprotoc-gen-connect-ktorFull-duplex bidi streaming is supported with Netty over HTTP/2. gRPC/gRPC-Web are still out of scope. See Known limitations for the honest matrix, and Conformance for what the suite actually exercises.
Connect-Ktor reuses Connect-Kotlin types and serialization strategies on the server.
Handlers return ResponseMessage, throw ConnectException, and speak the same error model clients already expect.
Client APIs, interceptors, transports, and Android setup belong in the official Connect-Kotlin docs and the connect-kotlin repository — this site does not restate them.
Code generation is split on purpose:
protoc-gen-connect-kotlin (official) produces clientsprotoc-gen-connect-ktor (this project) produces Ktor route handler interfacesBoth read the same .proto services.
A React app on Connect-ES and a Ktor service on Connect-Ktor can share one Buf module without inventing a parallel schema.
Full-duplex streams are supported with Netty over HTTP/2. It is a poor fit if you need gRPC wire compatibility. See Known limitations for engine and streaming constraints.
Prefer coexistence over conversion.
A single embeddedServer can expose /api/v1/... REST routes and /package.Service/Method Connect procedures at once.
Prefer protocol honesty over completeness theater. Unsupported axes stay ❌ in the matrix until the implementation and the conformance pins agree.
When the mental model clicks, Getting started is the shortest path to a handler running beside REST.