You can connect Apache Kafka to NATS by using Redpanda Connect as a bridge: Kafka acts as the input, Redpanda Connect optionally transforms each event, and NATS JetStream receives the processed messages as the output. This tutorial walks through a local Kafka-to-NATS integration using a Kafka topic, a Redpanda Connect YAML configuration, and a NATS JetStream subject.
By the end, you will have messages flowing from a Kafka topic named kafka-nats into NATS JetStream through Redpanda Connect.
This tutorial builds a simple Kafka-to-NATS bridge:
The flow looks like this:

Connecting NATS and Kafka is useful when you need to move event streams between systems with different operational models or integration needs. Common scenarios include:
NATS and Kafka overlap in some messaging and streaming capabilities, but they are often used for different parts of an architecture. Kafka is commonly used as a distributed event streaming platform for durable logs, data pipelines, and analytics. NATS provides a cloud-native connective fabric with subject-based messaging, request-reply, publish-subscribe, streams, object stores, and JetStream persistence.
NATS uses subject-based messaging. Publishers send messages to hierarchical string values called subjects, and subscribers listen on subjects or subject patterns. Kafka uses topics and partitions as the primary abstraction for organizing event streams.
NATS JetStream provides persistence for NATS messages and supports file- and memory-based storage. Kafka provides log-based storage for topics. In this tutorial, Kafka is the source topic and NATS JetStream is the destination for processed messages.
Before you start, install or have access to:
rpk clientThis tutorial uses a local, self-hosted NATS server. For a managed NATS environment, you can use Synadia Cloud, which provides a managed global NATS service with infrastructure, account and user management, and JetStream management.
This tutorial uses two separate NATS programs, distributed independently:
nats CLI, used to create and inspect streams and to run connection checks.nats-server binary, which runs the NATS server itself.Install the nats CLI with the official installer:
curl -sf https://binaries.nats.dev/nats-io/natscli/nats | shInstall the nats-server binary separately. On macOS you can use Homebrew:
brew install nats-serverFor other platforms, download the release archive that matches your operating system and CPU architecture from the nats-server releases page, then place the extracted nats-server binary on your PATH or in your working directory.
Start the NATS server with JetStream enabled and set the JetStream storage directory to the current folder:
nats-server -js --store_dir .If you placed the
nats-serverbinary in the current directory instead of on yourPATH, run it as./nats-server -js --store_dir ..
Keep this terminal window open. In a new terminal window, run a connection check:
nats server check connection -s nats://127.0.0.1:4222This validates that your local NATS server is reachable before you configure Redpanda Connect to publish to it.
JetStream persists a message only if a stream is configured to capture the subject the message is published on. Redpanda Connect publishes to the NATS subject kafka-nats-subject (configured in Step 4), so you must create a stream that captures that subject before you start the bridge. If no stream captures the subject, the JetStream publish from Redpanda Connect fails and no messages are stored.
Create a stream named kafka-nats that captures the kafka-nats-subject subject:
nats stream add kafka-nats --subjects "kafka-nats-subject" --storage memory --defaultsThe --defaults flag accepts the default values for all other stream options; omit it to be prompted for each option interactively instead. This example uses memory storage, so the stream’s messages are cleared when the server restarts. Use --storage file if you want them persisted under the --store_dir location.
The kafka-*.sh helper scripts used below ship in the bin/ directory of your Apache Kafka installation, and server.properties is the broker configuration file in its config/ directory. Run these commands from the directory where you extracted Kafka, and adjust the paths if your layout differs.
Start the Kafka server by pointing it to the broker configuration file:
bin/kafka-server-start.sh config/server.propertiesAfter Kafka starts, create a topic named kafka-nats:
bin/kafka-topics.sh --create --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 --topic kafka-natsThis topic is the source that Redpanda Connect will consume from.
You can create a Kafka console consumer to verify that publishing and consumption work inside Kafka before you add NATS to the flow:
bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic kafka-nats --from-beginningThis step is optional. Once Kafka validation is complete, Redpanda Connect will consume messages from the same topic and forward them to NATS.
Download Redpanda Connect with curl:
curl -LO https://github.com/redpanda-data/redpanda/releases/latest/download/rpk-darwin-arm64.zipIMPORTANT: The download artifact can differ by operating system and CPU architecture. Use the Redpanda Connect download that matches your environment.
Create a local binary directory, add it to your PATH, and unzip the rpk command line client:
mkdir -p ~/.local/binexport PATH=$PATH:~/.local/binunzip rpk-darwin-arm64.zip -d ~/.local/bin/Confirm that the installation succeeded:
rpk --versionCreate a Redpanda Connect configuration file named connect.yaml. In this configuration:
input.pipeline transforms each JSON message.output.1input:2 kafka:3 addresses:4 - localhost:90925 topics:6 - kafka-nats7 consumer_group: kafka-nats-group8
9pipeline:10 processors:11 - sleep:12 duration: 50ms13 - mapping: |14 root.company = this.data.company.name15 root.name = this.data.company.contactperson.name16 root.email = this.data.company.contactperson.email.hash("sha256")17 root.orderdate = this.data.dateoforder18
19output:20 nats_jetstream:21 urls: [ "nats://127.0.0.1:4222" ]22 subject: "kafka-nats-subject"The input.kafka section tells Redpanda Connect where to read events from:
addresses: The Kafka bootstrap server. This example uses localhost:9092.topics: The topic or topics to consume. This example uses kafka-nats.consumer_group: The Kafka consumer group. This example uses kafka-nats-group.These fields identify the Kafka source for the bridge.
The pipeline section extracts fields from the nested source JSON and writes a flatter output message:
company: The company namename: The name of the person who placed the orderemail: A SHA-256 hash of the contact person’s email addressorderdate: The order dateThis shows how Redpanda Connect can process messages while moving them between Kafka and NATS.
The output.nats_jetstream section tells Redpanda Connect where to publish processed messages:
urls: The NATS server URL. This tutorial uses nats://127.0.0.1:4222.subject: The NATS subject used for the published messages. This example uses kafka-nats-subject.Run Redpanda Connect with the configuration file:
rpk connect -c connect.yamlYou should see output similar to this:
INFO Running main config from specified file @service=benthos benthos_version=24.1.9 path=connect.yamlINFO Launching a Redpanda Connect instance, use CTRL+C to close @service=benthosINFO Output type nats_jetstream is now active @service=benthos label="" path=root.outputINFO Input type kafka is now active @service=benthos label="" path=root.inputThis confirms that Redpanda Connect has started the Kafka input and the NATS JetStream output.
Publish each object below as an individual JSON message to the kafka-nats Kafka topic. The source messages use a nested structure and include an unhashed email address.
Open a Kafka console producer in a new terminal:
bin/kafka-console-producer.sh --bootstrap-server localhost:9092 --topic kafka-natsPaste each JSON object below on its own line. The console producer sends every line as a separate Kafka message, and the Redpanda Connect mapping expects each message to contain a single data object.
1{"data":{"company":{"name":"JD Inc.","contactperson":{"name":"John Doe","email":"john.doe@jdmail.com"}},"price":"1050.00","dateoforder":"12/07/2024"}}2{"data":{"company":{"name":"Smith Enterprises","contactperson":{"name":"Jane Smith","email":"jane.smith@semail.com"}},"price":"1200.00","dateoforder":"15/07/2024"}}3{"data":{"company":{"name":"Tech Solutions","contactperson":{"name":"Mark Brown","email":"mark.brown@tsmail.com"}},"price":"980.00","dateoforder":"18/07/2024"}}4{"data":{"company":{"name":"Innovate LLC","contactperson":{"name":"Lucy Green","email":"lucy.green@illcmail.com"}},"price":"1150.00","dateoforder":"20/07/2024"}}5{"data":{"company":{"name":"Global Corp","contactperson":{"name":"Michael White","email":"michael.white@gcmail.com"}},"price":"1300.00","dateoforder":"22/07/2024"}}6{"data":{"company":{"name":"Future Tech","contactperson":{"name":"Laura Blue","email":"laura.blue@ftmail.com"}},"price":"1075.00","dateoforder":"25/07/2024"}}7{"data":{"company":{"name":"Bright Ideas","contactperson":{"name":"David Black","email":"david.black@bimail.com"}},"price":"1250.00","dateoforder":"28/07/2024"}}8{"data":{"company":{"name":"NextGen Inc.","contactperson":{"name":"Olivia Gray","email":"olivia.gray@ngmail.com"}},"price":"1100.00","dateoforder":"30/07/2024"}}9{"data":{"company":{"name":"Prime Solutions","contactperson":{"name":"Paul Brown","email":"paul.brown@psmail.com"}},"price":"995.00","dateoforder":"02/08/2024"}}10{"data":{"company":{"name":"Smart Innovations","contactperson":{"name":"Emily White","email":"emily.white@simail.com"}},"price":"1400.00","dateoforder":"05/08/2024"}}11{"data":{"company":{"name":"Elite Enterprises","contactperson":{"name":"James Black","email":"james.black@eemail.com"}},"price":"1180.00","dateoforder":"08/08/2024"}}After publishing messages to Kafka, inspect the NATS stream data:
nats stream view kafka-natsYou can also view a stream summary:
nats stream reportExample output:
Obtaining Stream stats
╭───────────────────────────────────────────────────────────────────────────────────────────────╮│ Stream Report │├────────────┬─────────┬───────────┬───────────┬──────────┬─────────┬──────┬─────────┬──────────┤│ Stream │ Storage │ Placement │ Consumers │ Messages │ Bytes │ Lost │ Deleted │ Replicas │├────────────┼─────────┼───────────┼───────────┼──────────┼─────────┼──────┼─────────┼──────────┤│ kafka-nats │ Memory │ │ 0 │ 11 │ 1.7 KiB │ 0 │ 0 │ │╰────────────┴─────────┴───────────┴───────────┴──────────┴─────────┴──────┴─────────┴──────────╯The report confirms 11 messages were consumed from Kafka and published to NATS JetStream.
If the Redpanda Connect mapping is working correctly, the transformed messages stored in NATS look similar to the following (the first 10 of the 11 messages are shown):
1[2 {"company":"JD Inc.","email":"/y2xKnsBxZ9svYXLJYreF+KvZcGz30sSCii0dOt5RHs=","name":"John Doe","orderdate":"12/07/2024"},3 {"company":"Smith Enterprises","email":"J/XjAZzFMk1wE5b4m/G/T5uOAeRd6ep/TNUw51RA8Rs=","name":"Jane Smith","orderdate":"15/07/2024"},4 {"company":"Tech Solutions","email":"HFxJTvcjZ+Oq4VEAn2In9doLTGTekKIlA4F9WmSceAY=","name":"Mark Brown","orderdate":"18/07/2024"},5 {"company":"Innovate LLC","email":"g2Kov5zhGrqBF6D4DnX/vG6qkby5w1cpvGO9W0ZVHow=","name":"Lucy Green","orderdate":"20/07/2024"},6 {"company":"Global Corp","email":"kTintSH97blGqknuTP4mJahDEdYR0upEqBs7/sS+Coc=","name":"Michael White","orderdate":"22/07/2024"},7 {"company":"Future Tech","email":"cF2sFbDnLWrWwg7LHedliIU4MFBSTBtT2MItO3/FXxQ=","name":"Laura Blue","orderdate":"25/07/2024"},8 {"company":"Bright Ideas","email":"nR80FyCZTH/hvNb+7v5Nj2l9ShrNuWnjMdh+omhAHuU=","name":"David Black","orderdate":"28/07/2024"},9 {"company":"NextGen Inc.","email":"lG+gaAuCan4yptV7AFNe5k+Pfne1+qunin4BGN6k38M=","name":"Olivia Gray","orderdate":"30/07/2024"},10 {"company":"Prime Solutions","email":"jMqGCWexvhOMRGfYQJE0VrQE6uzVNjT1LhGA+EYNziM=","name":"Paul Brown","orderdate":"02/08/2024"},11 {"company":"Smart Innovations","email":"imyi4RNgnsQLs1T2HyhWM58cGhEL+Sg9eP6Sqaf10h8=","name":"Emily White","orderdate":"05/08/2024"}12]Messages from Apache Kafka can now flow to NATS through the Redpanda Connect pipeline.
If you need the commands, configuration files, or sample data for reference, they are available in this GitHub repository.
Check that Kafka is running, the kafka-nats topic exists, and the addresses value in connect.yaml matches your Kafka bootstrap server. For this tutorial, the expected value is localhost:9092.
Confirm that the NATS server is still running with JetStream enabled and that the urls value in connect.yaml matches the NATS server address. In this tutorial, the expected URL is nats://127.0.0.1:4222.
Also confirm that a JetStream stream capturing the kafka-nats-subject subject exists. The nats_jetstream output publishes through JetStream, and JetStream stores a message only when a stream is configured to capture its subject. If that stream is missing, the publish fails and no messages reach NATS. Run nats stream report to confirm the kafka-nats stream is present, or create it as shown in Step 1.
The Redpanda Connect mapping processor reshapes each source event. It extracts selected nested fields, hashes the email value with SHA-256, and writes a flatter JSON object to NATS.
The pipeline mapping expects each message to contain a data object with the nested structure shown in the sample payload. Sending each object as its own event makes the transformation apply to each order independently.
In this tutorial, you connected Apache Kafka to NATS using Redpanda Connect. Kafka served as the source system, Redpanda Connect acted as the bridge and stream processing layer, and NATS JetStream received the processed messages.
NATS can serve as a connective fabric for applications and data flows across cloud, on-premises, and edge environments. For a managed NATS option, Synadia Cloud provides a managed global service for NATS with infrastructure, account and user management, and JetStream management.
For more practical examples, visit NATS by Example. To avoid managing NATS infrastructure yourself, you can sign up for a free Synadia Cloud account and start building with NATS.
Want help from the NATS experts? Meet with our architects to get help tailored to your use case and environment.



News and content from across the community