Library / SDK
LGouellec/streamiz avatar
LGouellec/streamiz

Streamiz brings the Kafka Streams programming model to .NET

.NET Stream Processing Library for Apache Kafka 🚀

545 stars82 forksC#MIT

At a glance

What is it?
Streamiz is a C# library for building Kafka stream topologies in .NET, published as a set of NuGet packages covering the core, schema registry serializers, Prometheus and OpenTelemetry metrics, and Azure remote storage, with a documented gap against Kafka Streams around standby replicas.
Who is it for?
Streamiz fits a .NET team that wants to write Kafka stream processing in C# and needs schema registry serialization, Prometheus or OpenTelemetry metrics and Azure remote storage without stitching four packages together itself. Do not plan on feature parity with Kafka Streams, because the project's own comparison marks standby replicas as not supported with no plan for now.
Can I use it commercially?
Yes. MIT 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 29 days ago.
What is it written in?
Mainly C#, 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

A .NET library built around the Kafka Streams model

Streamiz is described as a .NET stream processing library for Apache Kafka, and the way it positions itself is through a comparison with Kafka Streams rather than through a claim of its own. The README carries a table that lines up features side by side, with columns for Kafka Streams supported, Streamiz supported and a comment, and the first rows are stateless processors, the RocksDb store, the InMemory store and the Transformer and Processor API, all marked as supported on both sides.

The API in the sample code follows that model closely. A StreamBuilder holds the topology, streams and tables are declared on it, a topology is built from the builder, and a KafkaStream is constructed from that topology and a configuration object before the processing starts.

There is a trademark note worth repeating, since it sets the boundary of the project. Kafka is a registered trademark of the Apache Software Foundation, licensed for use by Streamiz, and the project states that it has no affiliation with and is not endorsed by the Apache Software Foundation. This is an independent implementation with a compatible programming model, not an official Apache project.

The NuGet packages are split by concern

The package list is where the scope of the project becomes clear, because it is not one package with optional extras. Streamiz.Kafka.Net is the core, and the rest are separate distributions: a schema registry package, Streamiz.Kafka.Net.SchemaRegistry.SerDes, which itself comes in Avro, Protobuf and JSON variants, two metrics packages, one for Prometheus and one for OpenTelemetry, and Streamiz.Kafka.Net.Azure.RemoteStorage for Azure remote storage.

That structure is a design statement. Serialization format, metrics backend and storage layer are all pluggable and independently versioned, which suits teams that have standardised on one serializer and one metrics stack, and it lets you take the core without taking a schema registry client at all.

The trade-off is dependency count. A service that wants Avro serialization, Prometheus metrics and Azure storage pulls three extra packages, and each has its own release cadence to track. The packages are published on nuget.org with prerelease versions available, and the README points there for the current versions rather than pinning numbers in the documentation.

Building a topology with StreamBuilder

The sample application in the README is short enough to read in one pass, and it shows the shape of the API. The configuration is a StreamConfig with two serializer type parameters, which is where the StringSerDes serializer is bound to the stream, and it carries the application id and the bootstrap servers:

csharp
static async System.Threading.Tasks.Task Main(string[] args)
{ 
    var config = new StreamConfig<StringSerDes, StringSerDes>();
    config.ApplicationId = "test-app";
    config.BootstrapServers = "localhost:9092";

After that the topology is assembled on a builder, with a stream and a table declared, the table backed by an in-memory store, a join between them, and the result written to another topic:

csharp
    var kstream = builder.Stream<string, string>("stream");
    var ktable = builder.Table("table", InMemory.As<string, string>("table-store"));

    kstream.Join(ktable, (v, v1) => $"{v}-{v1}")
           .To("join-topic");

    Topology t = builder.Build();
    KafkaStream stream = new KafkaStream(t, config);

The store argument is passed as part of the table declaration rather than configured globally, which is how the per-operator state stores are selected. The topology is then built into an immutable Topology and handed to a KafkaStream together with the config.

Starting the stream and disposing it on cancel

Running the topology is where the last piece of the sample appears, and the disposal handling is the detail worth copying. The stream is started asynchronously, and a handler on Console.CancelKeyPress disposes it:

csharp
    await stream.StartAsync();
}

Disposing the stream on interrupt is what stops the application from leaving a running consumer group behind when you stop it with Ctrl-C. A Kafka Streams equivalent has the same requirement, and it is the kind of line that gets left out of quickstarts and then shows up as a hung shutdown in a container that is being killed.

The instance is otherwise long-lived, since it holds the runtime that executes the topology, and the whole application is a Main method that builds, starts and waits. There is no host or dependency injection container in the sample, which is a fair indication that the library is designed to be driven from whatever application shape you already have.

The comparison table names the one gap

The feature table in the README is short and one row of it is the important one. Stateless processors are supported, the RocksDb store is supported, the InMemory store is supported, and the Transformer and Processor API is supported. Standby replicas are the exception: the Kafka Streams column is marked, the Streamiz column is empty, and the comment says no plan for now.

That is a real functional difference rather than a cosmetic one, and it is exactly the kind of thing that table is for. Standby replicas are a Kafka Streams feature for scaling stateless processing across instances, so a workload that relies on that mechanism has no equivalent here.

The table also shows the shape of the library relative to its Java counterpart. Streamiz implements the familiar processing model in C#, including the Transformer and Processor API, but the operations Kafka Streams offers that are tied to its own runtime internals, such as standby replicas, are the ones that do not carry over automatically. Read the table as a statement about parity, and it is a fairly complete one apart from that row.

The Gitpod demo runs a producer and a consumer

The quickest way to see the library work is the Gitpod setup the README links to, and it is described as three steps rather than as a code sample. Step one is to wait for the run task, which finishes a few seconds after a message appears saying to enjoy Streamiz. Step two is to switch to the producer terminal and send sentences or words, with the sample case described as counting the number of words. Step three is to switch to the consumer terminal and check the aggregation result.

The point of that walkthrough is that it exercises the whole path without any local Kafka setup. The producer writes to a topic, the topology consumes and aggregates, and the consumer terminal shows the aggregate, which is the fastest way to see whether your environment can talk to a broker and whether the serializers line up.

The repository supports that with a .gitpod.yml, a .gitpod.Dockerfile, an environment directory and a run-demo.sh script, and the demo is also how the project itself verifies a change end to end.

Docs, solution layout and the build tooling

The documentation lives on lgouellec.github.io/streamiz, and the repository builds it with Sphinx. The Makefile at the root is a minimal Sphinx makefile with the source directory set to docs and the build directory to build, a help target, and a pattern rule that routes any other target to sphinx-build, plus a local workaround target for a specific sphinx-build binary. It is a documentation makefile, not a build system for the library itself, which is a .NET solution, kafka-stream-net.sln, pinned to a global.json for the SDK version.

The source is organised into directories that map onto the packages: core, serdes, metrics, remote and launcher, with test alongside, plus an environment directory for the demo. There are also maintenance scripts, update-client-kafka.sh and update-version.sh, a key.snk for strong naming, a roadmap.md, a CONTRIBUTING.md and a .circleci directory alongside the GitHub workflows.

One inconsistency is worth noting if you follow the build badges. The Sonar Cloud quality badges in the README point at the master branch, while the repository's default branch is develop, so the coverage and quality figures you see may describe a different branch from the one you would pull.

Releases, licence and the pace of change

Streamiz is MIT licensed, with the badge and the LICENSE file in the repository, and it is not archived. The release history shows v1.8.2 published on 2026-09-24, v1.8.1 on 2026-04-15 and v1.8.0 on 2026-03-12, and the last push to the repository was on 2026-09-24, the same day as the latest tag.

The gaps between those tags are irregular, several months between 1.8.1 and 1.8.2, and that is worth planning around. A team that pins Streamiz to a specific version will be waiting for the next tag when it needs a fix, and the absence of a formal release policy in the README means the cadence is not something the project commits to.

For a library that sits in the data path of a Kafka application, the practical approach is to pin a version deliberately, test the upgrade against your own topics and schemas, and treat the update-client-kafka.sh and update-version.sh scripts as evidence of how the client and library versions are moved forward together, since the Kafka client and the stream layer have to agree.

Editorial conclusion

Streamiz fits a .NET team that wants to write Kafka stream processing in C# and needs schema registry serialization, Prometheus or OpenTelemetry metrics and Azure remote storage without stitching four packages together itself. Do not plan on feature parity with Kafka Streams, because the project's own comparison marks standby replicas as not supported with no plan for now. Before you commit, check three things: that the serializers you need exist as packages, since Avro, Protobuf and JSON each ship separately, that the client version your broker expects is what the topology config sets, and that the branch you follow is the one the build badges track, since the quality badges point at master while the default branch is develop. The licence is MIT, the latest release is v1.8.2 from 2026-09-24, and the last push was on 2026-09-24.

Frequently asked questions

How do I install Streamiz in a .NET project?

Add the core package with `dotnet add package Streamiz.Kafka.Net`. The packages are listed on nuget.org, and separate packages cover schema registry serialization for Avro, Protobuf and JSON, Prometheus and OpenTelemetry metrics, and Azure remote storage.

Which Kafka Streams features does Streamiz support?

The comparison table in the README marks stateless processors, the RocksDb store, the InMemory store and the Transformer and Processor API as supported. Standby replicas are the exception, with the Streamiz column empty and a comment that there is no plan for now.

How do I build and run a Streamiz topology in C#?

Create a `StreamConfig` with the serializer types and set the application id and bootstrap servers, declare streams and tables on a `StreamBuilder`, build the topology, wrap it in a `KafkaStream` and await `StartAsync()`. The README sample also disposes the stream in a `Console.CancelKeyPress` handler.

Is Streamiz an official Apache Kafka project?

No. The README states that Kafka is a registered trademark of the Apache Software Foundation, licensed for use by Streamiz, and that Streamiz has no affiliation with and is not endorsed by the Apache Software Foundation. It is an independent .NET implementation with a comparable programming model.

What is the current Streamiz release and licence?

The project is MIT licensed and not archived, with the latest release v1.8.2 published on 2026-09-24 and the last push to the repository on the same date. The full documentation is published at lgouellec.github.io/streamiz.

Official sources

  1. LGouellec/streamiz on GitHub
  2. License: MIT
  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/lgouellec-streamiz.svg)](https://hysenlabs.com/projects/lgouellec-streamiz)

Was this useful?