Pulsar CLI – A portable command line client for Apache Pulsar

Pulsar CLI – A portable command line client for Apache Pulsar
By Matthias Petermann / on 19.10.2025

Motivation

When working with Apache Pulsar there are often situations in which you want to quickly access topics - for example for debugging, testing or automating message flows. The existing clients and UIs are powerful, but often heavy or not optimized for straightforward use in the shell.

pulsar-cli closes this gap: A compact command line tool that exposes the basic Pulsar operations directly: Reader, Consumer and Producer - without setup, containers or external dependencies.


Implementation in Go

The choice was consciously made in favor of Go because it allows statically linked, cross-platform binaries to be created - a significant advantage for tools that are intended to function portably and independently.

A simple cross-compiling is enough:

GOOS=linux   GOARCH=amd64 go build -o pulsar-cli
GOOS=darwin  GOARCH=arm64 go build -o pulsar-cli
GOOS=windows GOARCH=amd64 go build -o pulsar-cli.exe

The result is standalone programs for Linux, macOS and Windows - without shared libraries, without a runtime environment, without an installation process. Copy a binary, set environment variables, get started.


Architecture and construction

The tool follows a clear structure:

pulsar-cli/
├── LICENSE
├── Makefile
├── README.md
├── go.mod
└── main.go

All logic is in one file (main.go). The CLI is implemented via spf13/cobra and uses the official Pulsar Go client for communication.

When started, the tool registers three commands:

  • reader – reads messages from a certain point in the topic
  • consumer – receives messages via a subscription
  • producer – sends messages entered via stdin

The configuration is done exclusively via environment variables:

export PULSAR_URL=pulsar+ssl://broker.example.org:6651
export PULSAR_JWT=<token>    # optional

Example: Reading news

The Reader command can be used to retrieve messages from a topic. Metadata (topic, message ID, timestamp) is output on stderr, the payload on stdout.

pulsar-cli reader -t persistent://public/default/test

Output example:

INFO[0000] Reading from topic persistent://public/default/test ...
INFO[0001] received message msgID=0001 publishAt=2025-10-19T20:10:00Z
{"event":"status","value":"ok"}

This allows the payload to be further processed in a targeted manner:

pulsar-cli reader -t mytopic | jq '.event'

Example: Consuming news

The Consumer works with a Pulsar subscription and automatically confirms messages after successful receipt. The same applies here: log output on stderr, user data on stdout.

pulsar-cli consumer -t persistent://public/default/test -s demo-sub

Example output:

INFO[0000] Consuming from topic persistent://public/default/test with subscription demo-sub ...
INFO[0002] received message msgID=0002 publishAt=2025-10-19T20:15:04Z
{"metric":"cpu_load","value":0.23}

The output can be integrated directly into monitoring or testing pipelines.


Example: Send messages

The Producer reads line-by-line data from stdin and sends it to the specified topic. Each successfully sent message is confirmed with metadata.

echo '{"event":"deploy","status":"ok"}' | pulsar-cli producer -t persistent://public/default/test

Log output to stderr:

INFO[0000] Producing messages to topic persistent://public/default/test (Ctrl+D to quit)
INFO[0000] sent message topic=persistent://public/default/test time=2025-10-19T20:30:00Z

This means that pulsar-cli can be seamlessly integrated into scripts or CI/CD processes - for example as part of automated tests, data feeds or health checks.


UNIX best practices

pulsar-cli consistently follows the classic UNIX principles:

Stream Content Example
stdout User data – i.e. messages or JSON content `pulsar-cli consumer …
stderr Diagnosis, status, logging INFO[0001] received message ...

This separation allows:

  • stable use in shell pipelines
  • machine-readable further processing
  • clean logging without mixing the data streams

The behavior is based on tools like curl or jq: stdout belongs to content, stderr belongs to observation.


Conclusion

pulsar-cli is a practical tool for anyone who wants to integrate Pulsar into existing automation or diagnostic processes.

A single binary is enough – no setup, no runtime dependencies, no additional components. The CLI is clearly structured Behavior predictable and script-friendly. With just a few lines of Go code This creates a tool that measurably simplifies Pulsar workflows - fast, portable and transparent.

🔗 Source code: https://forge.ext.d2ux.net/OpenLab/pulsar-cli


Image credit: The Pulsar logo is a registered trademark of the Apache Software Foundation. Use in the context of editorial reporting in accordance with the ASF trademark and logo guidelines.