# How to Open a Uni-Directional QUIC Stream in Iroh

> Learn how to open a uni-directional QUIC stream in Iroh using conn.open_uni().await. This guide shows you how to get a SendStream for write-only operations quickly.

- Repository: [number zero/iroh](https://github.com/n0-computer/iroh)
- Tags: how-to-guide
- Published: 2026-07-15

---

**Open a uni-directional QUIC stream in Iroh by calling `conn.open_uni().await?` on an established `Connection`, which returns a `SendStream` that supports only write operations.**

Iroh provides an ergonomic QUIC abstraction built on the `noq` crate that simplifies working with uni-directional streams for one-way data transmission. Learning how to open a uni-directional QUIC stream in Iroh is essential for implementing fire-and-forget messaging patterns or sending requests without expecting immediate responses. This article walks through the implementation details found in the `n0-computer/iroh` repository, including concrete examples from the production codebase.

## Understanding Uni-Directional QUIC Streams in Iroh

Uni-directional streams in Iroh are **send-only** channels that allow data transmission in a single direction. Once opened, these streams support write operations but explicitly disallow reads, making them ideal for scenarios where you need to push data to a peer without awaiting a response.

The underlying implementation delegates to the Noq connection's `open_uni()` method, wrapped in Iroh's high-level `Connection` API.

## Opening a Send-Only Stream with `open_uni()`

In [`iroh/src/endpoint/connection.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint/connection.rs) at lines 874-875, the `Connection` struct exposes the `open_uni()` method:

```rust
let mut send_stream = conn.open_uni().await?;

```

This async call returns an `OpenUni<'_>` future that resolves to a `quic::SendStream`. The method signature defined in [`iroh/src/endpoint/connection.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint/connection.rs) forwards the request to the internal Noq connection, providing a standardized interface for stream creation.

## Error Handling Patterns

Iroh's codebase demonstrates consistent error handling when opening uni-directional streams. The `.anyerr()` method converts underlying QUIC errors into the crate's unified error type:

```rust
let mut stream = conn.open_uni().await.anyerr()?;

```

For operations requiring additional diagnostic context, use `.std_context()`:

```rust
let mut stream = conn.open_uni().await.std_context("failed to open uni stream")?;

```

Both patterns appear throughout the test suite and production code in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs) (lines 2115-2133 and 2362-2364), ensuring that stream creation failures provide actionable error messages.

## Real-World Implementation Examples

### Client Connections in Examples

The file [`iroh/examples/remote-info.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/examples/remote-info.rs) at line 68 demonstrates a practical implementation:

```rust
let mut stream = conn.open_uni().await.anyerr()?;

```

This pattern appears after establishing a connection and before transmitting remote node information, showing the standard workflow for application developers.

### Internal Socket Abstraction

In [`iroh/src/socket.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/socket.rs) at line 2859, the codebase uses a direct unwrap when success is guaranteed by surrounding logic:

```rust
let mut stream = conn.open_uni().await.unwrap();

```

This internal usage demonstrates that while application code should handle errors explicitly, Iroh's own socket implementation may use `.unwrap()` in controlled contexts where prior validation ensures the connection remains active.

### Endpoint Management

The [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs) file contains multiple references to `open_uni()` in complex scenarios involving multiplexed streams and connection management. These implementations show the pattern integrated into larger async workflows:

```rust
let mut send = conn.open_uni().await.anyerr()?;

```

These call sites demonstrate how uni-directional streams fit into Iroh's broader QUIC endpoint architecture, particularly when managing concurrent stream operations.

## Summary

- **Single async call**: Use `conn.open_uni().await?` to create a uni-directional stream from any active `Connection`.
- **Write-only semantics**: The resulting `SendStream` supports only write operations, making it suitable for one-way data transmission.
- **Source location**: The method is defined in [`iroh/src/endpoint/connection.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint/connection.rs) at lines 874-875.
- **Error handling**: Convert errors using `.anyerr()?` for standard Iroh error types or `.std_context()` for custom messages.
- **Usage patterns**: Examples appear in [`iroh/examples/remote-info.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/examples/remote-info.rs) (line 68) and [`iroh/src/socket.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/socket.rs) (line 2859).

## Frequently Asked Questions

### What is the difference between uni-directional and bi-directional streams in Iroh?

Uni-directional streams, created with `open_uni()`, are **send-only** and do not support reading data from the peer, making them ideal for fire-and-forget messages. Bi-directional streams allow both reading and writing, typically used for request-response patterns where data must flow in both directions.

### How do I handle errors when opening a uni-directional stream?

The `open_uni()` method returns a `Result` that you should handle using Iroh's error conversion utilities. Call `.anyerr()?` to convert to the standard Iroh error type, or use `.std_context("message")?` to add descriptive context before propagating the error.

### Can I read from a stream opened with `open_uni()`?

No. The `SendStream` returned by `open_uni()` is strictly write-only. Attempting to read from this stream type will fail at compile time because the type does not implement read methods. Use bi-directional streams if you need to receive data from the peer.

### Where is the `open_uni()` method defined in the Iroh source code?

The method is defined on the `Connection` struct in [`iroh/src/endpoint/connection.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint/connection.rs) at lines 874-875. According to the `n0-computer/iroh` source code, this implementation forwards the call to the underlying Noq connection's `open_uni()` method while integrating with Iroh's error handling and async runtime.