ruststream 0.7.5

Async messaging framework for Rust: broker-agnostic traits, router, codecs, and a conformance harness for broker authors.
Documentation
---
sidebar_position: 5
title: CLI
description: "The ruststream command runs a service and prints its AsyncAPI document through cargo run; cargo generate scaffolds a new one."
---

# CLI

The `ruststream` command runs a service and prints its AsyncAPI document through `cargo run`; `cargo generate` scaffolds a new one.

`ruststream run` executes `cargo run -- run` against the crate's `Cargo.toml`, and `ruststream asyncapi gen` executes `cargo run -- asyncapi gen`.
The service's own binary does the work: the `main` that [`#[ruststream::app]`](./app-macro.md) generates understands both commands.
That `main` hands the commands to [`run_main`](api:ruststream::runtime::cli::run_main), and the [`runtime::cli`](api:ruststream::runtime::cli) module documents them.
`cargo run -- run` and `cargo run -- asyncapi gen` therefore give the same result without the command installed.
The same [run](./running/run.md) is one call from code.
`-p` points at another crate or its `Cargo.toml`, and `--release` builds in release mode.
[`asyncapi gen`](../asyncapi/generation/cli-gen.md) needs the service crate's `asyncapi` feature; the starter template enables it.
The template's console logs come from its `logging` feature.
`cargo generate` comes from the [cargo-generate](https://github.com/cargo-generate/cargo-generate) project; a broker crate ships templates of its own for its transport.

## Example

Install the command:

```bash
cargo install ruststream --features cli
```

Scaffold a service from the in-memory starter template:

```bash
cargo generate --git https://github.com/powersemmi/ruststream templates/memory --name my-service
cd my-service
```

The template writes a crate whose `main` is generated by `#[ruststream::app]`:

```text
Cargo.toml
src/main.rs
src/orders.rs
src/routes.rs
```

Run it; `Ctrl+C` stops it gracefully:

```bash
ruststream run
```

```text
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.02s
     Running `target/debug/my-service run`
2026-10-16T07:49:57.254761Z  INFO ruststream::lifecycle starting service service=my-service version=0.1.0 brokers=1 subscribers=2
2026-10-16T07:49:57.254790Z  INFO ruststream::lifecycle broker connected broker="ruststream::memory::MemoryBroker"
2026-10-16T07:49:57.254844Z  INFO ruststream::dispatch subscriber started subscriber=orders input="my_service::orders::Order"
2026-10-16T07:49:57.254854Z  INFO ruststream::dispatch subscriber started subscriber=cancellations input="my_service::orders::Order"
2026-10-16T07:49:57.254859Z  INFO ruststream::lifecycle service running subscribers=2
2026-10-16T07:50:00.281593Z  INFO ruststream::lifecycle shutdown signal received
2026-10-16T07:50:00.281755Z  INFO ruststream::lifecycle service stopped
```

Print the AsyncAPI document:

```bash
ruststream asyncapi gen
```

```text
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.02s
     Running `target/debug/my-service asyncapi gen`
{
  "asyncapi": "3.1.0",
  "info": {
    "title": "my-service",
    "version": "0.1.0"
  },
  "defaultContentType": "application/json",
  "channels": {
    "cancellations": {
      "address": "cancellations",
...
```

Write it as YAML, to a file, or for a crate in another directory:

```bash
ruststream asyncapi gen --yaml
ruststream asyncapi gen -o asyncapi.json
ruststream asyncapi gen -p ../my-service
```