CLI tool
sauljabin/kaskade avatar
sauljabin/kaskade

kaskade: a terminal UI for Kafka topics and records

kaskade is a text user interface for kafka, which allows you to interact and consume topics from your terminal in style!

1,044 stars22 forksPythonMIT

At a glance

What is it?
kaskade puts Kafka in a terminal interface: an admin mode for browsing and editing topics, partitions and consumer groups, and a consumer mode that reads records and decodes them as JSON, Avro or Protobuf with or without a Schema Registry. It is built with Textual, works over TLS, SASL or Amazon MSK IAM, and everything is keyboard driven.
Who is it for?
Adopt kaskade if you work with Kafka from a terminal and want to inspect lag, replicas and consumer groups without a management application, and if you need to read a record as Avro or Protobuf to find out what a producer is actually sending. Do not adopt it to manage a production cluster's configuration at scale, because it is a terminal tool for a human, and note that it can create, edit and delete topics.
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 2 days ago.
What is it written in?
Mainly Python, 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

Kafka, without leaving the terminal

kaskade is a terminal UI for Kafka, and the two sentences that describe it are the whole pitch. `kaskade admin` shows your topics, partitions and consumer groups and lets you create, edit and delete topics. `kaskade consumer` reads records from a topic and decodes them as JSON, Avro or Protobuf, with or without a Schema Registry. Everything works from the keyboard.

The choice of a TUI rather than a web console is a statement about the audience. Kafka is an infrastructure tool, and the people who need to look at a topic's lag at eleven at night are usually already in a terminal, often over SSH into a bastion. A keyboard-driven interface with a copy buffer is the right tool for that, and the fact that the copy action goes through an OSC 52 compatible terminal means you can pull a record out of the tool and into a bug report without a mouse.

The tool is published on PyPI as kaskade and in Homebrew, it is MIT licensed, and the site is sauljabin.github.io/kaskade. The author is Saúl Piña, and the last push was on 2026-10-13, with the repository not archived.

The project is built with Textual, which the acknowledgements credit, and it is sponsored by LittleHorse.

The admin mode, and the thirty second refresh

The administration feature list is four items, and the first one is a catalogue.

You browse topics, partitions, consumer groups and group members, and you inspect topic configuration, lag, replicas and record counts. You create, edit, delete and filter topics without leaving the TUI, and the topic metadata and metrics refresh every thirty seconds by default, or on demand.

That refresh interval is a design decision worth noticing. A Kafka admin tool that polls continuously is a tool that generates load on the cluster, and a tool that only refreshes on a keypress is a tool that shows you stale numbers. Thirty seconds is a compromise that suits a human watching a screen, and the on-demand refresh covers the case where you need the number now.

The set of things you can inspect is the set that matters when something is wrong with a topic: how far behind the consumers are, where the replicas are, how many records there are, and what the topic configuration actually says. The list of group members is the one that is easy to overlook, and it is the fastest way to find out that a consumer group has an unexpected member.

And the destructive part, create, edit and delete, is deliberate. This is a tool for the person who owns the cluster, not a read-only dashboard.

Decoding, and what happens when a record will not decode

The consumption feature list is the longest section in the README, and it is where the engineering is.

Keys and values are deserialised as bytes, primitives, JSON, Avro or Protobuf, including Confluent Schema Registry and the native Apicurio Registry v3. Registry Protobuf messages and referenced schemas are resolved without generated classes, which saves you from generating code for a schema that may not exist yet. And you can choose raw, Apicurio or Confluent framing separately for keys and values when decoding with local schemas, which is the level of control you need when the key uses one framing and the value another.

Then the ergonomics. You filter records by key, value, header or partition. You start from the earliest offsets or from explicit partition and offset selections, so you can look at exactly one record in the middle of a partition.

The failure behaviour is the part that shows the tool has been used in anger. It keeps consuming when a key, value or header fails to decode, and shows it as bytes next to the error. A tool that stopped at the first undecodable record would be useless against a real topic, because a schema that changed halfway through a partition is the normal case rather than the exception, and the record you were looking for is usually after it.

Bytes can be shown as Base64, hex, byte arrays or escaped bytes, and individual records can be copied or exported as JSON.

Connections, registries and timeouts

The connections and configuration section is short, and each item answers a question that comes up the first time you point a tool at a real cluster.

Kafka, Registry and AWS settings are kept in an INI file, or passed on the command line, so a connection can be named and reused rather than retyped. Operation timeouts can be raised for slow or distant clusters, which matters because the default that feels fine against a local broker will hang against one across an ocean.

On authentication, the tool connects through TLS, SASL, Confluent Cloud, or Amazon MSK IAM authentication. The MSK IAM path is the one that requires a specific dependency, and the repository carries example policy files for it in the examples/ directory, including an admin policy, a consumer policy and a combined admin and consumer policy, which is a helpful touch for anyone setting up the IAM role for the first time.

For schemas, you can use Confluent Schema Registry, the native Apicurio Registry, or Apicurio's Confluent-compatible API. The third option is the pragmatic one: a lot of teams run Apicurio but have tooling written against the Confluent API shape, and supporting both means you do not have to choose which registry to run based on which client your tools speak to.

The examples directory also holds client.ini and settings.yaml, and a set of consumer record fixtures for the different formats, including the Apicurio, Confluent, byte, error, JSON and string cases, which are the test inputs for the decoding path.

A keyboard-first interface

The terminal experience section is three bullets, and they are the reason a Kafka tool can be pleasant to use.

You navigate entirely by the keyboard with arrow and Vim-style shortcuts, so the muscle memory you have from editing works here too. You can customise the themes and the keybindings, which is what you need when the default mapping collides with what your terminal sends for something else. And you copy data through an OSC 52 compatible terminal, which is the mechanism that lets a selected record end up on your clipboard even when the TUI is running over SSH on a machine you do not control.

That last one is the detail that separates a TUI that works over SSH from one that does not, and the documentation has a section on OSC 52 compatibility in the usage guide.

The project also keeps a MANUAL_TESTING.md in the repository root, alongside DEVELOPMENT.md, MIGRATION.md, USAGE.md and a RELEASE_CHECKLIST.md. The release checklist and the migration guide in particular are the marks of a project with users: a migration document for every major version means the breaking changes are written down rather than discovered, and the manual testing document means the parts of a TUI that cannot be unit tested, the actual key presses, have a written procedure.

There is also a SECURITY.md, and the README asks for vulnerabilities to be reported privately through that policy rather than in a public issue.

Installing it and connecting to a broker

There are two installation routes and two commands.

bash
brew install kaskade
bash
pipx install kaskade

Homebrew for macOS and Linux, and pipx for the isolated Python install that keeps a command line tool out of your project environment. The tool supports Linux and macOS, and the PyPI page carries the badges for both.

Connecting is one flag, and the two modes take the broker address the same way:

bash
kaskade admin -b my-kafka:9092
bash
kaskade consumer -b my-kafka:9092 -t my-topic

The admin mode needs only the bootstrap brokers, and the consumer mode adds the topic to read. The -b flag is the bootstrap address, and everything else, credentials, registry, TLS material and timeouts, comes from the INI file or the command line.

The entry point is declared in the package metadata as kaskade = kaskade.main:cli, and the version is dynamic, taken from the version control tags with hatch-vcs and a tag pattern, so a build from a checkout gets the right version without a number being maintained by hand.

The dependency stack and the project's own rules

The pyproject dependency list tells you how much of this is Textual and how much is Kafka.

confluent-kafka with the avro, json and protobuf extras is the client, and fastavro is there alongside it for Avro work done directly rather than through the client. grpcio-tools is the Protobuf toolchain, httpx is the HTTP client for the registry APIs, jsonschema and pyyaml handle the schema and configuration files, and tree-sitter with tree-sitter-json is a parser, which is how the tool can filter records by looking inside a JSON payload rather than matching it as text.

Two dependencies are worth a line each. aws-msk-iam-sasl-signer-python is the Amazon MSK IAM signing support, which is a niche feature that most Kafka tools skip. And cloup is a command line parser built on Click with more control over the help output, which is what a TUI with subcommands needs.

Textual is pinned to a range with a comment explaining why: Kaskade overrides private DataTable members, and the cap is lifted once issue 151 removes them. That comment is a good example of a maintainer being explicit about a technical debt item in the dependency file, with the issue number attached.

The project supports Python 3.10 to 3.14 and the classifiers list every version in that range. The development dependencies include testcontainers, which is how you test against a real broker rather than a mock, textual-dev for the Textual development tooling, faker for data generation, mypy with a mypy.ini in the root, ruff, black, typos and pre-commit.

And there is an AI Assistance section in the README, which says Kaskade is developed with AI assistance and that every AI-assisted change is reviewed and tested before it is merged. Stating that in the README is the right call, and it pairs with the AGENT.md and CLAUDE.md files in the repository root, which tell an agent how to work on the project.

Editorial conclusion

Adopt kaskade if you work with Kafka from a terminal and want to inspect lag, replicas and consumer groups without a management application, and if you need to read a record as Avro or Protobuf to find out what a producer is actually sending. Do not adopt it to manage a production cluster's configuration at scale, because it is a terminal tool for a human, and note that it can create, edit and delete topics. Before you start, read the USAGE document for the connection settings, and check the MIGRATION document, because the project ships one for upgrading between major versions.

Frequently asked questions

What can kaskade do with Kafka?

It has two modes. kaskade admin shows topics, partitions and consumer groups and lets you create, edit and delete topics, with inspection of configuration, lag, replicas and record counts. kaskade consumer reads records from a topic and decodes them as JSON, Avro or Protobuf, with or without a Schema Registry.

Which schema registries does kaskade support?

Confluent Schema Registry, the native Apicurio Registry, or Apicurio's Confluent-compatible API. Registry Protobuf messages and referenced schemas are resolved without generated classes, and you can choose raw, Apicurio or Confluent framing separately for keys and values when decoding with local schemas.

How does kaskade behave when a record cannot be decoded?

It keeps consuming and shows the failing record as bytes next to the error, rather than stopping. Bytes can be displayed as Base64, hex, byte arrays or escaped bytes, and individual records can be copied or exported as JSON.

How do I install and connect kaskade to a broker?

Install it with brew install kaskade or pipx install kaskade, then run kaskade admin -b my-kafka:9092, or kaskade consumer -b my-kafka:9092 -t my-topic to read a topic. Connection, registry and AWS settings live in an INI file or on the command line, and operation timeouts can be raised for slow clusters.

Is kaskade still being developed?

The repository is not archived and the last push was on 2026-10-13, with releases v5.0.1 on 2026-09-21, v5.0.2 on 2026-09-27 and v5.1.0 on 2026-09-28. The project ships a MIGRATION document for upgrading between major versions and states that it is developed with AI assistance, with every such change reviewed and tested before merging.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. sauljabin/kaskade on GitHub
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/sauljabin-kaskade.svg)](https://hysenlabs.com/projects/sauljabin-kaskade)

Was this useful?