Library / SDK
google/cronet-transport-for-okhttp avatar
google/cronet-transport-for-okhttp

cronet-okhttp swaps OkHttp's network layer for Cronet

This package allows OkHttp and Retrofit users to use Cronet as their transport layer, benefiting from features like QUIC/HTTP3 support or connection migration.

571 stars53 forksJavaApache-2.0

At a glance

What is it?
The cronet-okhttp library lets an OkHttp or Retrofit application run its requests over Cronet instead of OkHttp's own transport, which is the way to get QUIC and HTTP3 on Android. It suits an existing OkHttp app that needs the newer protocol, and it gives up a substantial part of OkHttp's own feature set in the exchange.
Who is it for?
Adopt cronet-okhttp if your Android app already uses OkHttp or Retrofit and you have a concrete reason to need QUIC, HTTP3 or Cronet's connection migration behaviour, since the whole point is to keep your OkHttp facing API and change only the transport.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 11 days ago.
What is it written in?
Mainly Java, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the bridge does and what it bypasses

The package allows OkHttp and Retrofit users to use Cronet as their transport layer, benefiting from features like QUIC and HTTP3 support and connection migration. The mechanism is an interop layer, and the design principle stated in the documentation is to implement the full set of OkHttp APIs on top of Cronet. The catch is stated just as plainly. The entirety of OkHttp core is bypassed, which includes caching, retries, authentication and network interceptors, and those features have to be enabled directly on the Cronet engine or built on top of this library. That is a much larger trade than it first appears, because OkHttp's caching and retry behaviour is usually invisible to application code, so a team that adopts this library discovers the gap when a stale-response test starts failing. The library is also young. The recent releases are 0.1.0 and 0.1.1 on the same day in February 2026 and 0.1.2 on 2026-10-05, which places the current version at a 0.1.x release on a project with an Apache-2.0 licence, and the last push to the repository was on 2026-10-12.

Adding the dependency and obtaining a CronetEngine

Installation is a Gradle dependency in your app's build.gradle file, with the version specified explicitly.

gradle
implementation 'com.google.net.cronet:cronet-okhttp:VERSION'

The available versions are listed in the Google Maven Repo, and the example given in the documentation is 0.1.1. You also need a dependency on OkHttp, which you likely already have, and a dependency on core Cronet. There are several ways to obtain a CronetEngine instance, and the recommended one is a Google Play Services provider, which loads the Cronet implementation from the platform. The reason given is that the application then does not pay the binary size cost of carrying Cronet, and the platform delivers the latest updates and security fixes. The documentation also recommends falling back to plain OkHttp when the platform-wide Cronet is unavailable, for example on a device without Google Play Services or one whose platform has been tampered with, which is a sensible default for a mixed device population. The Play Services provider dependency is added separately.

gradle
implementation "com.google.android.gms:play-services-cronet:18.1.1"

Installing the provider and building the engine

Before creating a Cronet engine you need to initialise the bindings between your application and Google Play Services, and the call is a single line.

java
CronetProviderInstaller.installProvider(context);

The documentation is upfront about the awkwardness: the installProvider call is asynchronous, and the sample omits handling of failures and synchronisation for brevity, with a pointer to the sample application shipped with the library for something closer to production use. That is a real caveat for anyone pasting the snippet into a release build, since an unhandled asynchronous failure at startup is exactly the kind of thing that is invisible in development. The engine itself is then created with the standard builder.

java
CronetEngine cronetEngine = new CronetEngine.Builder(context).build();

The CronetEngine.Builder documentation is the reference for any custom configuration. That is the point at which most of the decisions that used to live in an OkHttp client, certificate pinning and proxies among them, have to be made instead.

Interceptor or call factory, and why the order matters

There are two ways to use the library, either as an OkHttp application interceptor or as a Call factory, and the documentation recommends matching the choice to how your app is built. If your application makes extensive use of application interceptors, using the library as an interceptor will be more practical, since you can keep your current interceptor logic and just add one more.

java
CronetEngine engine = new CronetEngine.Builder(context).build();

Call.Factory callFactory = new OkHttpClient.Builder()
   .addInterceptor(CronetInterceptor.newBuilder(engine).build())
   .build();

There is a note about ordering, and it is the kind that bites. Add the Cronet interceptor last, otherwise the subsequent interceptors will be skipped. If your existing chain has a logging or auth interceptor after the point where you insert the Cronet one, it will quietly stop running. The other option exists for the case where you do not make heavy use of OkHttp's interceptors, or you are working with another library that requires Call.Factory instances, such as Retrofit, in which case the custom call factory is the better choice.

java
CronetEngine engine = new CronetEngine.Builder(context).build();

Call.Factory callFactory = CronetCallFactory.newBuilder(engine).build();

Both paths accept the builder configuration options that directly affect how the interop layer behaves.

Using the call factory with plain OkHttp and with Retrofit

Once the call factory exists, the rest of the code is ordinary OkHttp, which is the point of the whole exercise. A request looks exactly like the built-in API.

java
String run(String url) throws IOException {
  Request request = new Request.Builder()
      .url(url)
      .build();
  try (Response response = callFactory.newCall(request).execute()) {
    return response.body().string();
  }
}

The Retrofit case is almost identical, because Retrofit takes a call factory rather than a client.

java
Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    .callFactory(callFactory)
    .build();

The configuration story is where the two layers meet awkwardly. The transport libraries are configured in two ways, and the builders for both the interceptor and the call factory provide configuration options that directly affect how the interop layer behaves. Most of the network configuration, certificate pinning and proxies among them, should be done directly in the Cronet engine rather than on the OkHttp side. The maintainers are explicit that they are open to providing convenience utilities for configuring the Cronet engine and ask people to reach out with their use case, which tells you the current state of the ergonomics.

The incompatibilities that matter before you ship

The documentation keeps an explicit list of limitations and features the bridge does not provide, and it is worth reading it as a compatibility contract rather than a footnote. Beyond the wholesale bypass of OkHttp core, several differences are subtle. It is not possible to set multiple values for a single header key in outgoing requests, because Cronet uses the last value provided, and Accept-Encoding is populated automatically by Cronet based on the engine configuration with custom values ignored. The Response object does not have handshake, networkResponse or cacheResponse set, nor the sentRequestAtMillis and receivedResponseAtMillis timings, and the Request field under the response reflects the outermost layer rather than Cronet's internal transformations. Response parsing logic differs in places, with Cronet generally more lenient, silently dropping headers or falling back to defaults where OkHttp might throw, for example on status code parsing, and the documentation says this should not be a concern for typical usage. Error messages carry the same meaning but different detail. A request body with a null content type and a non-zero content length has its missing or empty Content-Type overridden to application/octet-stream with a warning to Logcat, because Cronet requires a non-empty Content-Type on upload. And the WebSocket protocol is not supported by Cronet, so it is not supported by this library either, which is a hard blocker for an app that also uses OkHttp's WebSocket support.

The interceptor-specific caveat and the platform dependency

Two more points close out the picture. The first is specific to the interceptor mode, where Call cancellation signals are propagated with a delay, which matters for an app with timeouts and for user-initiated cancels, since the request does not stop at the instant the caller asks. The second is the platform dependency, and it is the one that decides where this library can be used at all. Cronet has to come from somewhere: the Play Services provider, which needs Google Play Services on the device, or a bundled Cronet implementation, which costs binary size. The recommended path also involves a fallback to plain OkHttp when platform Cronet is unavailable, and a fallback path is a second code path with a different transport, which means a second set of behaviours to test. The project also points to an API reference hosted on the Android developer site, and the repository carries the usual Gradle build files including a WORKSPACE file and a third_party/ directory, along with java/ for the library and javatests/ for the tests. For a team evaluating this, the honest framing is that it is a Google-published bridge for one specific migration, from OkHttp's transport to Cronet's, on Android, with a documented list of what that migration costs.

Editorial conclusion

Adopt cronet-okhttp if your Android app already uses OkHttp or Retrofit and you have a concrete reason to need QUIC, HTTP3 or Cronet's connection migration behaviour, since the whole point is to keep your OkHttp facing API and change only the transport. Do not adopt it if you rely on OkHttp's caching, its retry logic or its network interceptors, because the documentation says all of OkHttp core is bypassed and those features have to be rebuilt on the Cronet engine or on top of the library. Verify two things before you plan the work: that your devices can supply a Cronet implementation at all, since the recommended route is the Play Services provider with an OkHttp fallback for devices without it, and that you have read the incompatibilities list, because a silent difference in response parsing or a missing WebSocket support tends to surface in production rather than in tests. The practical first step is to add the Gradle dependency, build a CronetEngine, and run one request through CronetCallFactory before you touch your existing client configuration.

Frequently asked questions

What does cronet-okhttp do?

It lets OkHttp and Retrofit users use Cronet as their transport layer, which brings features like QUIC and HTTP3 support and connection migration. The design principle is to implement the full set of OkHttp APIs on top of Cronet.

How do I add the Cronet transport to an OkHttp app?

Add the Gradle dependency implementation 'com.google.net.cronet:cronet-okhttp:VERSION' to your build.gradle, obtain a CronetEngine, and either add a CronetInterceptor to your OkHttp client as the last interceptor or use CronetCallFactory.newBuilder(engine).build() as the call factory.

Which OkHttp features stop working with the Cronet transport?

The entirety of OkHttp core is bypassed, including caching, retries, authentication and network interceptors. Those features have to be enabled directly on the Cronet engine or built on top of the library.

Can I use WebSockets with cronet-okhttp?

No. The WebSocket protocol is not supported by Cronet, so it is not supported by this library either.

How do I get a CronetEngine on a device without Google Play Services?

The documentation recommends a Google Play Services provider so the application does not carry the binary size cost of Cronet, and it recommends falling back to plain OkHttp when platform-wide Cronet is not available, for example on a device without Google Play Services.

Where should I configure certificate pinning and proxies?

Directly in the Cronet engine rather than on the OkHttp side. The builders for the interceptor and the call factory only provide options that affect the interop layer, and most network configuration should be set on the engine.

Official sources

  1. google/cronet-transport-for-okhttp on GitHub
  2. Issues
  3. License: Apache-2.0
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/google-cronet-transport-for-okhttp.svg)](https://hysenlabs.com/projects/google-cronet-transport-for-okhttp)