Open-source project
elastic/elasticsearch-java avatar
elastic/elasticsearch-java

The official Java client for Elasticsearch, and the version rules you have to respect

Official Elasticsearch Java Client

525 stars300 forksJavaApache-2.0

At a glance

What is it?
elastic/elasticsearch-java exposes every Elasticsearch API as strongly typed Java requests and responses, and hands transport work to a low level REST client. The interesting part for adopters is the compatibility matrix, which is narrower than the forward compatibility claim suggests.
Who is it for?
Teams running Java services against Elasticsearch should adopt this client when their server version falls inside a supported branch, because the typed request and response layer removes hand written JSON handling. Projects that need to talk to several server majors at once, or that depend on features added in a newer Elasticsearch release, should treat the client release cycle as part of their upgrade planning.
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 17 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 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A typed Java layer over Elasticsearch's REST APIs

The Java client for Elasticsearch exists to stop application code from assembling and parsing JSON by hand. The project description calls it the official Java client for Elasticsearch, and it provides strongly typed requests and responses for all Elasticsearch APIs. That means a search call is expressed through Java request objects and a Java response object rather than a string body and a map of keys.

The project sits in the middle of a larger stack. Elasticsearch itself is described as a distributed, RESTful search engine built for production scale workloads, used for vector search, full text search, logs, metrics, application performance monitoring and security logs. The client is the Java-side entry point to that engine, and the README lists usage paths for creating an index, indexing a document, getting documents, searching documents, updating documents, deleting documents and deleting an index. Those seven operations are the documented surface that a new user is pointed at first.

The audience is narrow and clear: engineers writing Java services that need to search or index data. Anyone who is only consuming a search service over HTTP from another language has no reason to read this code.

Transport concerns are delegated to a low level REST client

The client deliberately does not own the network layer. The README states that the Java client delegates protocol handling to an http client such as the Elasticsearch Low Level REST client, which takes care of transport level concerns including http connection establishment and pooling, and retries. That boundary matters for anyone sizing an application: connection pooling and retry behaviour live below the typed API, so tuning them is a separate exercise from choosing request types.

The repository layout backs this up. Alongside the main java-client module there are directories named example-transports and rest5-client, plus an examples folder holding two projects, esql-article and realworld-app. The presence of several transport related modules suggests that swapping or comparing HTTP implementations is something the project accounts for, though the README does not enumerate the transports it supports.

There is a design record too. The docs/design folder holds notes on the major decisions behind the API, which is unusual to find in a client repository and worth reading before you build a large wrapper library around the typed classes.

Builders everywhere, but nulls instead of Optional

Two design decisions are spelled out in the design notes. Object construction follows the builder pattern, and nested objects can be created with builder lambdas, which the README says allows for clean and expressive DSL-like code. So instead of a long constructor call with a dozen arguments, you chain setters and pass lambdas for nested values.

The second decision is the more contentious one. Optional values are represented as null with @Nullable annotations rather than with the newer Optional type, and the reasoning given is that the Java ecosystem is still very null based. This is a deliberate trade-off, and you should know which side of it you are on. Using Optional inside the API would push null handling into every call site; using null with annotations keeps the signature shorter and matches much existing Java code, but it means the compiler will not warn you when a value is absent. If your team relies on static analysis to catch missing fields, check that your build is configured to read the @Nullable annotations, because the type system itself is not protecting you here.

Neither of these choices is documented as a limitation, so treat them as design intent you accept or work around.

Running Elasticsearch and Kibana locally with a single curl command

The README offers one concrete way to try the stack on your own machine. If you want to try Elasticsearch and Kibana locally, the documented command is below.

bash
curl -fsSL https://elastic.co/start-local | sh

After it runs, Elasticsearch answers on port 9200 and Kibana on port 5601 on localhost. That gives you a cluster and a UI to point a Java program at, without installing a distribution by hand. The README also links the download page for the latest Elasticsearch version and the sign-up page for a free trial of Elastic Cloud, for cases where you would rather not run anything locally.

For the Java side, the project points at the Installation and Connecting sections of the getting started documentation on elastic.co rather than listing dependency coordinates in the README. The same applies to the first real use: creating an index, indexing a document, searching and deleting are all documented as pages in the getting started guide, and the client itself ships no runnable snippet in the README. Expect to read those two guide sections, install the client from the coordinates given there, and connect to the localhost:9200 endpoint you just started.

Forward compatibility does not mean new features arrive automatically

The compatibility section carries the most useful warning in the README. The client is forward compatible, meaning it supports communicating with greater or equal minor versions of Elasticsearch without breaking. But it does not mean the client automatically supports new features of newer Elasticsearch versions; that only becomes possible after a release of a new client version. The example given is specific: a client at 8.12 will not automatically support the new features of Elasticsearch 8.13, and the 8.13 client is required for those.

So forward compatibility covers protocol level breakage, not feature coverage. If a server release introduces a new query option or a new request field, your client has to catch up. Language clients are also only backwards compatible with default distributions and without guarantees made.

The support table lists which server version maps to which client branch: the 9.x server line maps to the 9.x client branch, and the 8.x server line maps to the 8.x client branch, where the supported entry reads 8.17. The main branch is listed against main with no support value. Read that 8.17 line as a boundary: clients on the 8.x branch track one specific server release, so an application that stays on the 8.x client line does not get everything a newer 8.x server can do.

Major and minor releases move together, patches move on their own

Release cadence is split into two layers. Java client releases are synchronized with the Elasticsearch server for major and minor versions, while patches are released independently to allow for faster bugfixes. Compatibility is unaffected by that split: version 8.13.x of the client is compatible with server versions 8.13.y where y is greater than or equal to x.

The published release list shows both layers at work. v9.5.4 and v9.4.7 were both published on 2026-09-16, which is what parallel maintenance of the 9.x and 9.4 lines looks like from the outside, and v9.5.3 came on 2026-09-02. Two branches, two dates, one repository.

For a Java team this is the practical reason to track client releases at all: a patch release can arrive on its own, so pinning to an exact version is optional, while a new minor version is the point at which new server features become reachable. The last push to the repository was on 2026-10-06, and the release cadence visible in the tag list is steady across the two branches.

What the client does not cover, and what Apache 2.0 means here

Several things a new user might expect are simply absent from the documentation. The README does not document rollback behaviour for failed writes. It does not show how authentication or TLS is configured, deferring that to the getting started guide on elastic.co. It also does not list which transport implementations are supported, even though the repository holds an example-transports directory and a separate rest5-client module.

The licence is the Apache License 2.0, and the repository carries the corresponding LICENSE.txt and NOTICE.txt files. Apache 2.0 is permissive, which in practice means you can use the client inside a commercial product without buying a separate licence, and it carries the usual obligations around notices and, where applicable, patent grants. That is a statement about the licence terms themselves and not legal advice; if your organisation requires a specific licence review, the LICENSE.txt file in the repository is the place to start.

The repository also carries CHANGELOG.md, AGENTS.md, CLAUDE.md, CONTRIBUTING.md, a NOTICE.txt file and a build defined in build.gradle.kts with settings.gradle.kts and a buildSrc directory. That is the shape of a serious multi module Gradle project, and it means building the client from source is a real operation rather than a single jar download.

Editorial conclusion

Teams running Java services against Elasticsearch should adopt this client when their server version falls inside a supported branch, because the typed request and response layer removes hand written JSON handling. Projects that need to talk to several server majors at once, or that depend on features added in a newer Elasticsearch release, should treat the client release cycle as part of their upgrade planning. Before committing, check which branch of the client covers your server version, since the compatibility table lists 8.x only at 8.17, and confirm that the endpoints you need are present in that client release.

Frequently asked questions

How do I install the Elasticsearch Java client?

The README does not list dependency coordinates itself. It points to the Installation section of the getting started guide on elastic.co, and also links the Elasticsearch download page and the Elastic Cloud trial sign-up for getting a server to talk to.

Which Elasticsearch server versions work with the Java client?

The compatibility table maps 9.x server to the 9.x client branch and 8.x server to the 8.x client branch, where the supported value is 8.17. The main branch is listed against main with no support value.

Does a newer client automatically support new Elasticsearch features?

No. Forward compatibility means the client can talk to greater or equal minor server versions without breaking, but new server features need a new client release. The README uses 8.12 and 8.13 as the example, where the 8.13 client is required.

Is the Elasticsearch Java client actively maintained?

The repository is not archived and the last push was on 2026-10-06. Releases include v9.5.4 and v9.4.7 on 2026-09-16 and v9.5.3 on 2026-09-02, with patches released independently of major and minor versions.

Does the Java client handle connection pooling and retries itself?

No. Protocol handling is delegated to an http client such as the Elasticsearch Low Level REST client, which takes care of http connection establishment and pooling, and retries, as well as other transport level concerns.

Official sources

  1. elastic/elasticsearch-java 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/elastic-elasticsearch-java.svg)](https://hysenlabs.com/projects/elastic-elasticsearch-java)

Was this useful?