# Flows.rs
[](https://unlicense.org)
[](https://blog.rust-lang.org/2025/02/20/Rust-1.85.0/)
[](https://crates.io/crates/flows)
[](https://docs.rs/flows)
_"Τὰ πάντα ῥεῖ καὶ οὐδὲν μένει" — Heraclitus_
**Building blocks for [flow-based programming] (FBP) in Rust.**
This collection of crates implements a growing shrink-wrap inventory of
standard dataflow blocks for common use cases.
> [!TIP]
> 🚧 _We are building in public. This is presently under heavy construction._
[[Features](#-features)] |
[[Prerequisites](#%EF%B8%8F-prerequisites)] |
[[Installation](#%EF%B8%8F-installation)] |
[[Examples](#-examples)] |
[[Reference](#-reference)] |
[[Development](#%E2%80%8D-development)]
## ✨ Features
- Provides components for flow-based programming (FBP) based on [Tokio].
- Supports dataflow systems by providing reusable components called blocks.
- Built on the primitives provided by the [Async-Flow] project.
- Supports opting out of any feature using comprehensive feature flags.
- Adheres to the Rust API Guidelines in its [naming conventions].
- No licensing headaches: 100% free and unencumbered public domain software.
## 🛠️ Prerequisites
- [Rust](https://rust-lang.org) 1.85+ (2024 edition)
## ⬇️ Installation
### Installation via Cargo
```bash
cargo add flows
```
## 👉 Examples
### Importing the Library
```rust
use flows::{audio, hash, image, io, json, math, rand, text};
```
### Implementing Blocks
#### Implementing a `split_string` block
```rust
use flows::{Inputs, Outputs, Result};
/// A block that splits input strings based on a delimiter.
async fn split_string(delim: &str, mut ins: Inputs<String>, outs: Outputs<String>) -> Result {
while let Some(input) = ins.recv().await? {
for output in input.split(delim) {
outs.send(output.into()).await?;
}
}
Ok(())
}
```
#### Implementing an `add_ints` block
```rust
use flows::{Inputs, Outputs, Result};
/// A block that outputs the sums of input numbers.
async fn add_ints(mut lhs: Inputs<i64>, mut rhs: Inputs<i64>, sums: Outputs<i64>) -> Result {
loop {
let (a, b) = tokio::try_join!(lhs.recv(), rhs.recv())?;
match (a, b) {
(Some(a), Some(b)) => sums.send(a + b).await?,
_ => break,
}
}
Ok(())
}
```
## 📚 Reference
[docs.rs/flows](https://docs.rs/flows)
## 👨💻 Development
```bash
git clone https://github.com/artob/flows.rs.git
```
---
[](https://x.com/intent/post?url=https://github.com/artob/flows.rs&text=Flows.rs)
[](https://reddit.com/submit?url=https://github.com/artob/flows.rs&title=Flows.rs)
[](https://news.ycombinator.com/submitlink?u=https://github.com/artob/flows.rs&t=Flows.rs)
[](https://www.facebook.com/sharer/sharer.php?u=https://github.com/artob/flows.rs)
[](https://www.linkedin.com/sharing/share-offsite/?url=https://github.com/artob/flows.rs)
[Async-Flow]: https://github.com/artob/async-flow
[Tokio]: https://tokio.rs
[flow-based programming]: https://jpaulm.github.io/fbp/
[naming conventions]: https://rust-lang.github.io/api-guidelines/naming.html