Skip to content

The CLI

The ruststream command-line tool scaffolds projects and drives cargo with the framework's subcommands.

cargo install ruststream --features cli

A RustStream service is an ordinary Rust binary whose main is generated by #[ruststream::app]. The CLI does not introspect it; run and asyncapi gen shell out to cargo run against the target crate, and new writes a project.

Commands

ruststream new my-service              # scaffold a project (default --broker memory)
ruststream new my-service --broker nats     # Core NATS project
ruststream new my-service --broker nats-js  # NATS JetStream project
ruststream run                         # cargo run -- run, against ./Cargo.toml
ruststream run -p ./my-service         # against another crate
ruststream run --release               # release build
ruststream asyncapi gen                # print the AsyncAPI document
ruststream asyncapi gen -o spec.json   # write it to a file
ruststream asyncapi gen --yaml         # YAML instead of JSON

run and asyncapi gen take -p/--manifest-path (defaulting to the current directory) to point at a crate other than the working directory.

The generated entry point

#[ruststream::app] turns a builder function into a main that understands run and asyncapi gen, so there is no runtime boilerplate:

use ruststream::memory::MemoryBroker;
use ruststream::runtime::{AppInfo, RustStream};

#[ruststream::app]
fn app() -> RustStream {
    RustStream::new(AppInfo::new("orders", "0.1.0"))
        .with_broker(MemoryBroker::new(), |b| b.include(handle))
}

Because the dispatch lives in the generated binary, both ruststream run and a plain cargo run -- run start the service the same way. ruststream run is a convenience that finds the crate and forwards the command to cargo.

Scaffold layout

ruststream new writes a multi-file project so a fresh service starts idiomatic rather than as a single dumping-ground file:

my-service/
├── Cargo.toml
└── src/
    ├── main.rs      # #[ruststream::app], mounts the router
    ├── orders.rs    # #[subscriber] handlers, one with a reply
    └── routes.rs    # a Router collecting the handlers

--broker picks the broker wired into main.rs and the dependencies:

  • memory (default) - the in-process MemoryBroker, no external service; good for a first run or tests.
  • nats - Core NATS via ruststream-nats.
  • nats-js - NATS JetStream; orders.rs binds the consumer with a SubscribeOptions builder chain in the #[subscriber(..)] decorator (a durable pull consumer).

See the quick start to scaffold and run one.