Framework
apple/servicetalk avatar
apple/servicetalk

ServiceTalk: a JVM networking framework built on Netty, hosted under apple

A networking framework that evolves with your application

1,045 stars233 forksJavaApache-2.0

At a glance

What is it?
ServiceTalk is a Java network application framework that sits on Netty and offers protocol specific APIs, notably HTTP/1.x, HTTP/2.x and gRPC, plus client side load balancing and service discovery integration. The catch is its version scheme: 0.x releases are explicitly allowed to break API and ABI, so a framework dependency needs a version policy of its own.
Who is it for?
ServiceTalk fits a team that wants Netty's throughput without writing its protocol state machines, needs HTTP/2 or gRPC on the JVM, and is prepared to treat a 0.x version as something to pin and retest on every upgrade. It is the wrong choice if you need a stable API contract for external consumers, if your runtime is limited to the Java standard library, or if you want a client stack with a large body of third party integration.
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 3 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 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What ServiceTalk adds on top of Netty

ServiceTalk is described as a JVM network application framework with APIs tailored to specific protocols, with HTTP/1.x and HTTP/2.x given as examples, and it supports multiple programming paradigms. It is built on Netty, and the design goal stated in the README is to provide most of the performance and scalability benefits of Netty for the common networking protocols used in service to service communication.

That framing matters. Netty gives you channels, pipelines and byte buffers, and leaves protocol state machines to you. The work ServiceTalk takes off your hands is the part where you write an HTTP/1.1 parser, an HTTP/2 framing layer, or a gRPC transport, and get the concurrency and flow control right while doing it.

The README also names the client side of the story, calling out server support and what it calls smart client features, namely client side load balancing and service discovery integration. The module list in the repository backs that up with directories for dns-discovery-netty, circuit-breaker-api, circuit-breaker-resilience4j, capacity-limiter-api, grpc-api, grpc-netty and grpc-health, alongside the core client, server, concurrent, buffer and encoding modules.

The repository is hosted under the apple organisation, with the documentation at docs.servicetalk.io. The primary language is Java, and the stated minimum supported JDK version is 1.8. The topic tags list framework, grpc, http, http2, java, microservices, netty, reactive, reactive-streams and rpc, which is an accurate summary of the surface area.

This is a framework for service to service traffic on the JVM. It is not a web framework for serving HTML to browsers, and it is not a general purpose SDK collection. If your problem is an internal RPC mesh or a high volume API client, the shape fits. If your problem is a monolith with a handful of HTTP endpoints, the amount of machinery in front of you is larger than the problem.

The 0.x line is explicitly allowed to break API and ABI

The compatibility section is the paragraph every adopter should read first, and it is unusually blunt. ServiceTalk follows SemVer 2.0.0, and API and ABI breaking changes require a package renaming for that module to avoid runtime classpath conflicts. Then the note: 0.x.y releases are not stable and are permitted to break API/ABI.

The package renaming rule is a deliberate mitigation. If a module changes incompatibly, its package gets renamed, so a service that has one module pinned to an old version and another upgraded to a new version gets a clear classpath conflict at startup rather than a subtle behavioural difference at run time. That is a good pattern, and it only works if you are willing to treat a version bump as a breaking event.

The 0.x line is where the cost lands. The recent releases are 0.42.67 on 2026-10-01, 0.42.66 on 2026-08-26 and 0.42.65 on 2026-07-23, which is a steady cadence of patch numbers inside a pre-1.0 line. The number itself means nothing for compatibility, because the note tells you 0.42.68 is permitted to break API and ABI in the same way 0.42.67 could.

Two consequences follow for whoever owns the dependency. First, you cannot treat a ServiceTalk upgrade as a routine version bump in a dependency management tool. The classes may have moved packages, and a compile error is the good case. Second, if ServiceTalk is a transitive dependency of something you publish to external consumers, the stability of your own API is partly borrowed from a library that has not committed to stability.

The practical response is a policy rather than a hope. Pin an exact version, keep the upgrade as an explicit task with a test run, and read the release notes for the modules you actually use. The README itself points to the documentation site for the examples, which is where the per module details live.

The licence is Apache-2.0, and the repository also carries GOVERNANCE.adoc and MAINTAINERS.adoc, so the project states how decisions are made and who maintains it rather than leaving that implicit. The repository is not archived, and the last push was on 2026-10-19, so the branch and the published artifacts are in step.

Building the project with the Gradle wrapper

ServiceTalk uses Gradle as its build tool and only requires JDK 8 or higher to be pre-installed. The project ships the Gradle Wrapper, so there is no need to install Gradle on your machine beforehand. Contributors are pointed at CONTRIBUTING.adoc first, with a note that the file is the contribution guidelines.

The build command runs the tests and the code quality checks:

shell
$ ./gradlew build

Code coverage is deliberately not part of that default. The README says coverage uses JaCoCo and that it is not wired into ./gradlew build to keep the default build fast, so it is generated on demand. The aggregate report runs the tests first and then merges the per-module coverage data, and it lands in two places:

shell
$ ./gradlew testCodeCoverageReport

The HTML output goes to build/reports/jacoco/aggregate/html/index.html and the XML output to build/reports/jacoco/aggregate/jacocoAggregateReport.xml, the latter being the one meant for CI tooling. For a single module, the task is that module's jacocoTestReport, for example:

shell
$ ./gradlew :servicetalk-concurrent-api:jacocoTestReport

The aggregate configuration lives in gradle/jacoco.gradle and the per-module setup is applied by the ServiceTalk Gradle plugin, which is a hint that the plugin also does other things across the build.

The supported IDE is IntelliJ IDEA, and project files are generated on demand rather than committed:

shell
$ ./gradlew idea
$ idea .

On macOS the alternative is open servicetalk.ipr, which opens the same project as a workspace file.

Two contributor-facing details deserve a mention because they are the kind of thing that wastes an afternoon. Source code is UTF-8 encoded, and the README says the filesystem must support it, pointing at the JAVA_TOOL_OPTIONS environment variable set to -Dfile.encoding=UTF-8 for non-UTF-8 environments, and noting that editors and IDEs must also support UTF-8 to edit the source successfully. And dependencies are governed by lock files, so that changes to dependencies are intentional and do not go unnoticed. When you update dependencies, you make the intended modifications in gradle.properties first and then run:

shell
$ ./gradlew resolveAndLockAll --write-locks

That last point is a good signal about the project's culture. Dependency drift in a networking library is a supply chain problem, and the lock file discipline means the review of a dependency bump is a diff you can read.

Reading the module list to find the piece you actually need

The top level directory listing is the best documentation the repository offers about its own scope, and it is long. The naming convention is consistent: servicetalk- followed by a capability, then an implementation suffix where there is more than one.

The core is split into API and internal pairs, which is the same package renaming discipline seen in the compatibility note made visible in the directory structure. There is servicetalk-client-api and servicetalk-client-api-internal, servicetalk-concurrent-api, servicetalk-concurrent-api-internal and servicetalk-concurrent-internal, servicetalk-encoding-api and servicetalk-encoding-api-internal. The concurrent family is the widest, with servicetalk-concurrent-jdkflow, servicetalk-concurrent-reactivestreams, servicetalk-concurrent-test-internal and servicetalk-concurrent-api-test, which tells you the framework speaks both the JDK Flow API and Reactive Streams.

Protocol support is where the module count comes from. The data serialization modules alone cover several combinations of data format and JAX-RS generation: servicetalk-data-jackson, servicetalk-data-jackson3, servicetalk-data-protobuf, and their jersey variants at different versions and Jakarta levels, including servicetalk-data-jackson3-jersey4-jakarta11 and servicetalk-data-protobuf-jersey3-jakarta10. gRPC is split into servicetalk-grpc-api, servicetalk-grpc-internal, servicetalk-grpc-netty, servicetalk-grpc-protobuf and servicetalk-grpc-health.

Service discovery and resilience are separate opt-in modules rather than core. dns-discovery-netty is the DNS based discovery implementation. There is circuit-breaker-api and circuit-breaker-resilience4j, the latter being a bridge to the Resilience4j library, and capacity-limiter-api for load shedding. servicetalk-buffer-api and servicetalk-buffer-netty handle the buffer abstraction, and servicetalk-annotations and servicetalk-bom manage annotations and a bill of materials. servicetalk-bom is worth a second look: a BOM module lets you align the version of every ServiceTalk artifact in one place, which matters in a project that pulls in a dozen of them.

There is also servicetalk-examples, servicetalk-benchmarks, servicetalk-gradle-plugin-internal, servicetalk-dependencies and a top level buildSrc/ directory. The naming tells you what is public and what is not, which is the first thing to check when you find yourself importing from an internal package.

The README has a broken link and an unclosed AsciiDoc tag

The README is the project's front door, and it has a couple of rough edges worth knowing about before you spend time on it.

The contributor section links to the contribution guidelines with a reference written as xref:CONTRIBUTING.adoc, which is AsciiDoc cross-reference syntax that will not render as a clickable link in a plain Markdown view on GitHub. The file is there, at the top level of the repository, and its name is CONTRIBUTING.adoc, so the reference is pointing at something real.

That issue will not cost you more than a minute, but they are the reason the README is not the whole answer. It is a short document that points outward to docs.servicetalk.io for examples and to the per module documentation for the real API detail. The API surface of a framework with this many modules is far too large to fit in a README, so the README is functioning as a map rather than a manual.

That is the right division of labour, but it means the adoption decision cannot be made from the README alone. You will need the documentation site to answer practical questions such as how the client load balancer is configured, how the service discovery interface is implemented for a registry you already use, and how the HTTP/2 module differs from the HTTP/1.x one in terms of configuration surface.

The build documentation is where the README is most complete and most accurate, with the Gradle wrapper commands, the coverage tasks and the lock file procedure all given concretely. If you are contributing rather than consuming, that part is enough to get started on a first build.

Editorial conclusion

ServiceTalk fits a team that wants Netty's throughput without writing its protocol state machines, needs HTTP/2 or gRPC on the JVM, and is prepared to treat a 0.x version as something to pin and retest on every upgrade. It is the wrong choice if you need a stable API contract for external consumers, if your runtime is limited to the Java standard library, or if you want a client stack with a large body of third party integration. Before adopting, read the compatibility note in the README carefully, decide whether you can live with breaking API and ABI changes in a 0.x line, and check that the module set you need, whether that is grpc-netty, dns-discovery-netty or circuit-breaker-resilience4j, is published in the same release.

Frequently asked questions

What is ServiceTalk and what is it built on?

ServiceTalk is a JVM network application framework with APIs tailored to specific protocols such as HTTP/1.x and HTTP/2.x, and it is built on Netty. It provides server support plus client side features including load balancing and service discovery integration.

Is ServiceTalk's API stable in the 0.x releases?

No. The README states that 0.x.y releases are not stable and are permitted to break API and ABI, even though the project follows SemVer 2.0.0 and renames packages for modules with breaking changes to avoid runtime classpath conflicts. Pin an exact version and retest on every upgrade.

How do I build ServiceTalk from source?

Install JDK 8 or higher and run ./gradlew build, which runs the tests and code quality checks. The project ships a Gradle Wrapper, so Gradle does not need to be installed separately, and IntelliJ IDEA project files are generated with ./gradlew idea.

Which Java version does ServiceTalk support?

The minimum supported JDK version is 1.8. The project also requires a UTF-8 capable filesystem, and the README suggests setting JAVA_TOOL_OPTIONS to -Dfile.encoding=UTF-8 in non-UTF-8 environments.

Official sources

  1. apple/servicetalk on GitHub
  2. License: Apache-2.0
  3. Project website
  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/apple-servicetalk.svg)](https://hysenlabs.com/projects/apple-servicetalk)

Was this useful?