---
title: Feature matrix
description: Compare Rust feature activation and TypeScript SDK configuration with the network infrastructure each capability needs.
---

## Rust

Cargo features control what code is available. Builder methods control what runs inside an endpoint. External network infrastructure determines which paths are actually usable.

| Capability | Cargo selection | Builder activation | Active behavior | Infrastructure |
| --- | --- | --- | --- | --- |
| Direct QUIC, Identify, Ping, custom streams | Default (`std`, `quic`) | None required | Authenticated QUIC streams and built-in protocols | A mutually reachable UDP path |
| Direct TCP | `tcp` | `.tcp(...)`, `.tcp_multiaddr(...)`, or `.bind_tcp(...)` | Noise-authenticated Yamux streams over TCP | A mutually reachable TCP path |
| Portable TCP | `default-features = false, features = ["smoltcp"]` | `Endpoint::portable(...).smoltcp(...).listen(...).build()` | TCP, Noise XX, Yamux, Identify, Ping, and custom streams on a caller-driven loop | Your smoltcp device, interface, clock, and entropy |
| Reachability probing | `nat` | `.autonat_server(server)` or a `NatConfig` with probe servers | AutoNAT probes and reachability state | Reachable AutoNAT server |
| Relayed connections and DCUtR | `nat` | `.relay(relay)` or relay-bearing `.nat_config(...)` | Reservations, relay races, and hole punching | Reachable Circuit Relay v2 server |
| Gossipsub | `pubsub` | `.gossipsub()` or gossipsub `.gossipsub_config(...)` | Signed gossipsub messages | At least one compatible mesh peer |
| Signed discovery | `discovery` | `.discovery()` or `.discovery_config(...)` | Signed beacons, shared peer book, and optional automatic dialing | A connected discovery peer; relay optional for direct-only addresses |
| Local-link discovery | `mdns` | `.mdns()` or `.mdns_config(...)` | Local observations, shared peer book, and optional automatic dialing | Multicast-capable local network and interface |

## Default std API

The default dependency selection enables `std` and `quic`. `Endpoint` and `EndpointBuilder` require `std`; the QUIC methods below also require `quic`.

Available on the std `Endpoint`:

- Address publication: `listen`, `listen_all`
- Direct connections: `connect`, `cancel_connect`, `dial`, `dial_ip4`, `dial_ip6`, `disconnect`
- State: `peer_id`, `connected_peers`, `is_peer_ready`, `peer_info`
- Streams: `add_protocol`, `open_stream`, `send_stream`, `close_stream_write`, `reset_stream`, `abandon_stream`
- Driving: focused waits `wait_peer_ready`, `nat_wait_path` (nat), `wait_ping_rtt`; event loops `wait`, `next_event`, `next_wake`; non-blocking `poll`
- Shutdown: `close`

Available on `EndpointBuilder` with `quic`:

- Bind: `listen_on`, `listen_on_multiaddr`, `listen_default`, `quic`, `quic_multiaddr`, `quic_dual_multiaddr`, `quic_dual_stack`, `bind_quic`, `bind_quic_multiaddr`, `bind_quic_dual_stack`
- Configuration: `quic_limits`

`EndpointBuilder::bind` is available with `std`, but needs at least one configured transport. Enable `quic` or `tcp` before adding a corresponding bind.

## TCP API

Compiled with `features = ["tcp"]`:

- Bind: `listen_on`, `listen_on_multiaddr`, `tcp`, `tcp_multiaddr`, `bind_tcp`
- Configuration: `tcp_config`
- Routing: QUIC addresses use QUIC; `/tcp` dials use TCP

## Portable API

With default features off, `Endpoint::portable(identity, entropy)` starts a `PortableEndpoint` builder. Call `build(transport)` with the caller-provided `Transport`. The resulting endpoint uses `poll(now)` and `next_deadline(now)` instead of the std endpoint's blocking wait methods. It never reads a system clock or starts a runtime.

The `smoltcp` feature adds a shared embedded TCP stack. It includes portable mDNS; enable `pubsub` for pubsub and signed discovery, `portable-autonat` for AutoNAT, and `portable-relay` for relay circuits.

## NAT API

Compiled with `features = ["nat"]`:

- Activation: `relay`, `autonat_server`, `nat_config`
- Attempts: `connect`, `cancel_connect`, `nat_wait_path` (migration; removed in #181)
- Events: `take_nat_events`, `next_nat_event`
- State: `reachability`, `active_reservation`, `path`

> **Warning**
>
> An AutoNAT server enables reachability probing but does not supply a relay path. Configure a relay for circuits, reservations, and relay-assisted DCUtR.

## Pubsub API

Compiled with `features = ["pubsub"]`:

- Activation: `gossipsub`, `gossipsub_config`
- Topics: `subscribe`, `unsubscribe`, `publish`
- Events: `take_gossipsub_events`, `next_gossipsub_event`

## Discovery API

Compiled with `features = ["discovery"]`, which includes the `nat` and `pubsub` Cargo features:

- Activation: `discovery`, `discovery_config`
- Shared policy: `peer_discovery_config`
- State: `known_peers`
- Events: `take_discovery_events`, `next_discovery_event`

Activating discovery also activates default pubsub and the NAT agent. A relay remains optional for direct discovery, but required for relayed paths and relay-assisted punching.

## mDNS API

Compiled with `features = ["mdns"]`, which includes the `nat` Cargo feature but not `pubsub`:

- Activation: `mdns`, `mdns_config`
- Shared policy: `peer_discovery_config`
- State: `known_peers`
- Events: `take_discovery_events`, `next_discovery_event`
- mDNS lifecycle: `shutdown` sends goodbyes and stops mDNS without closing the endpoint

mDNS discovers peers only on multicast-capable local links. Its address claims remain unauthenticated until the selected transport verifies the peer identity. Automatic mDNS-triggered attempts are direct-only and never activate a configured relay or HOP CONNECT. `Endpoint::shutdown` sends TTL-zero goodbyes and permanently stops mDNS; QUIC and TCP keep working. With both `discovery` and `mdns` enabled, both sources use one bounded peer book and one automatic-dial state.

## TypeScript

Node.js and React Native accept the same `Minip2pConfig`. It selects the capabilities and infrastructure used by an endpoint.

| Capability | Configuration | Active behavior | Infrastructure |
| --- | --- | --- | --- |
| Direct QUIC/TCP, Identify, Ping, custom streams | `secretKey`; optional `transports` and `protocols` | `Minip2p.create` starts the endpoint; transport default is dual-stack QUIC only | A mutually reachable UDP or TCP path |
| Gossipsub | Always on | Signed outbound pubsub and strict inbound validation | At least one compatible mesh peer |
| Signed discovery | `discovery: { topic, ... }` | Signed beacons, shared peer book, optional auto-dial | A connected discovery peer |
| Local-link discovery | `mdns: true` or options | mDNS, shared peer book, optional auto-dial | A multicast-capable local network; mobile hosts also need local-network permissions |
| Reachability probing | `autonatServers: [...]` | AutoNAT probes | Reachable AutoNAT server |
| Relayed paths and DCUtR | `relays: [...]` | Reservations, relay race, fallback, hole punching | Reachable Circuit Relay v2 server |

An AutoNAT server still does not provide a relay path. Discovery and mDNS can dial advertised direct addresses without a relay. See [Networking and events](/typescript/networking-and-events) for configuration examples, and the [TypeScript API](/reference/typescript-api) reference for the full configuration map.

## Full Rust API

[docs.rs publishes the Rust API for the latest release](https://docs.rs/minip2p-rs/latest/minip2p/). That reference uses the default `std` and `quic` features. Check the [published feature list](https://docs.rs/crate/minip2p-rs/latest/features) for the optional flags.

Generate the default rustdoc locally:

```bash
cargo doc -p minip2p-rs --no-deps --open
```

To include every optional std feature in one local build:

```bash
cargo doc -p minip2p-rs --features nat,pubsub,discovery,mdns,tcp,relay-server --no-deps --open
```

For the `no_std + alloc` view, disable defaults. Add the portable features your application uses, for example:

```bash
cargo doc -p minip2p-rs --no-default-features --features smoltcp,pubsub,portable-autonat,portable-relay --no-deps --open
```
