Kafka
Maven
Dependencies
Programming
Software Development

Kafka Maven Dependencies

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Most Java applications that use Kafka need fewer Maven dependencies than people expect. For standard producers, consumers, and admin operations, the core artifact is kafka-clients; you add other Kafka artifacts only when you are actually using those APIs.

Start with kafka-clients

The Apache Kafka documentation uses org.apache.kafka:kafka-clients as the main dependency for producer, consumer, and admin code. If your application sends messages, reads topics, or creates topics programmatically, this is the first artifact to add.

xml
1<properties>
2    <kafka.version>4.1.1</kafka.version>
3</properties>
4
5<dependencies>
6    <dependency>
7        <groupId>org.apache.kafka</groupId>
8        <artifactId>kafka-clients</artifactId>
9        <version>${kafka.version}</version>
10    </dependency>
11</dependencies>

Using a property keeps all Kafka artifacts aligned if the project later grows beyond the client library.

A minimal producer with only kafka-clients looks like this:

java
1import java.util.Properties;
2import org.apache.kafka.clients.producer.KafkaProducer;
3import org.apache.kafka.clients.producer.ProducerRecord;
4
5public class ProducerDemo {
6    public static void main(String[] args) {
7        Properties props = new Properties();
8        props.put("bootstrap.servers", "localhost:9092");
9        props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
10        props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
11
12        try (KafkaProducer<String, String> producer = new KafkaProducer<>(props)) {
13            producer.send(new ProducerRecord<>("orders", "order-1", "created"));
14            producer.flush();
15        }
16    }
17}

That single dependency is enough for a large share of Kafka-backed services.

Add kafka-streams Only for Streams Applications

If the application uses the Kafka Streams DSL or Processor API, add kafka-streams as a separate dependency. Do not include it just because the project uses Kafka somewhere else.

xml
1<dependency>
2    <groupId>org.apache.kafka</groupId>
3    <artifactId>kafka-streams</artifactId>
4    <version>${kafka.version}</version>
5</dependency>

That dependency is for topology-building code such as joins, aggregations, state stores, and stream transformations.

java
1import java.util.Properties;
2import org.apache.kafka.common.serialization.Serdes;
3import org.apache.kafka.streams.KafkaStreams;
4import org.apache.kafka.streams.StreamsBuilder;
5import org.apache.kafka.streams.StreamsConfig;
6
7public class StreamApp {
8    public static void main(String[] args) {
9        Properties props = new Properties();
10        props.put(StreamsConfig.APPLICATION_ID_CONFIG, "uppercase-app");
11        props.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
12        props.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass());
13        props.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass());
14
15        StreamsBuilder builder = new StreamsBuilder();
16        builder.stream("input-topic")
17               .mapValues(value -> value.toUpperCase())
18               .to("output-topic");
19
20        KafkaStreams streams = new KafkaStreams(builder.build(), props);
21        streams.start();
22        Runtime.getRuntime().addShutdownHook(new Thread(streams::close));
23    }
24}

If the application never uses this API, keep the dependency list smaller and clearer.

Keep Versions Aligned and Let Frameworks Help

The safest rule is to keep all Kafka artifacts on the same version. Mixing kafka-clients from one release with kafka-streams from another can produce confusing dependency problems.

If you are using a platform such as Spring Boot, check whether the framework already manages Kafka versions. In that case, overriding individual Kafka artifacts casually may create more problems than it solves. The best dependency graph is usually the smallest one that matches the framework's supported version set.

Message Format Libraries Are a Separate Decision

Many dependency questions that sound like "What Kafka dependency do I need?" are really questions about serialization. The Kafka client library gives you core serializers and deserializers for primitive and common Java types. If you need JSON, Avro, or Protobuf, those libraries are added because of the message format, not because Kafka itself requires them.

That distinction matters because it keeps pom.xml understandable. Kafka transport dependencies and data-format dependencies solve different problems and should be chosen independently.

Testing Dependencies Should Stay Focused

For automated tests, resist the urge to add a large pile of Kafka-related libraries just because examples online do. If the goal is to exercise producer or consumer logic, start with the smallest setup that actually gives confidence, such as a targeted integration test against a local broker or test container.

Good dependency hygiene is not only about build speed. It also reduces classpath conflicts and makes upgrades more predictable.

Common Pitfalls

  • Adding kafka-streams to every Kafka project even when the code only produces or consumes records.
  • Mixing Kafka artifact versions in the same Maven build.
  • Confusing Kafka transport dependencies with separate serializer or schema dependencies.
  • Overriding framework-managed Kafka versions without checking the wider dependency graph.
  • Treating pom.xml setup as the hard part while ignoring producer configuration, consumer groups, and topic design.

Summary

  • Use kafka-clients for standard producer, consumer, and admin code.
  • Add kafka-streams only when the project actually uses the Streams API.
  • Keep Kafka artifact versions aligned through one Maven property or framework-managed version.
  • Choose serializer libraries separately from Kafka transport libraries.
  • Keep the dependency list minimal and justified by the application's real requirements.

Course illustration
Course illustration

All Rights Reserved.