Feature matrix
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 |
.listen_on("/ip4/0.0.0.0/tcp/4001")? or .listen_on_multiaddr(...) with a /tcp address |
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 - Connection attempts:
connect,cancel_connect,disconnect - State snapshots:
peer_id,connected_peers,is_peer_ready,peer_info,connection_id,connection_remote_addr,connection_info,path,bound_addresses - Streams:
add_protocol,open_stream(returns the connection and stream IDs),send_stream,close_stream_write,reset_stream,abandon_stream(each addressed by connection and stream ID), andStreamWriterfor whole writes with a deferred close - Ping:
ping(RTT arrives asEndpointEvent::PingRttMeasured) - Driving: blocking
wait(every event, including capability variants, or the deadline, or an interruption); non-blockingpoll;wait_handleto interrupt a blockedwait - Identify advertisement:
set_external_addresses - Shutdown:
close
Available on EndpointBuilder with quic:
- Listen:
listen_on,listen_on_multiaddrwith/udp/<port>/quic-v1addresses (at most one per IP family),listen_default(dual-stack QUIC wildcards), thenbind - Configuration:
quic_limits
EndpointBuilder::bind is available with std, but needs at least one listen address (otherwise it fails with BindError::Options(EndpointOptionsError::NoTransport)). Enable quic or tcp before listening on a corresponding address.
TCP API
Compiled with features = ["tcp"]:
- Listen:
listen_on,listen_on_multiaddrwith/tcp/<port>addresses - Configuration:
tcp_config(connection, buffer, timeout and Yamux limits) - Routing: QUIC addresses use QUIC;
/tcpcandidates use TCP
Portable API
With default features off, Endpoint::portable(identity, entropy) starts a PortableEndpoint builder. Call build(transport) with any caller-provided Transport. The resulting endpoint runs the same engine and event order as the std Endpoint, but uses poll(now) and next_deadline(now) instead of the blocking wait; Connection attempts use connect(target, now) and cancel_connect(id, now), and poll(now) returns Vec<EndpointEvent>, including enabled capability variants. It never reads a system clock or starts a runtime, and it has no raw swarm access.
Capabilities are builder setters behind their own features, over any transport: pubsub (Gossipsub; with portable-mdns also signed discovery), portable-mdns (.mdns(io, config) over any MdnsIo, .peer_discovery_config(..)), portable-autonat, and portable-relay. Relays need circuit operations: build with build_with_circuits over a CircuitTransport; build refuses relay configuration.
The smoltcp feature adds a shared embedded TCP stack and includes portable mDNS; .smoltcp(stack) builds TCP and mDNS on it and returns the same PortableEndpoint.
NAT API
Compiled with features = ["nat"]:
- Activation:
relay,autonat_server,nat_config - Configuration:
circuit_limits(relay circuits’ Yamux limits) - Attempts:
connectraces direct candidates against a relay leg;cancel_connect - Events:
EndpointEvent::Nat(..)viawaitorpoll - State:
reachability,active_reservation
Pubsub API
Compiled with features = ["pubsub"]:
- Activation:
gossipsub,gossipsub_config - Topics:
subscribe,unsubscribe,publish - Events:
EndpointEvent::Gossipsub(..)viawaitorpoll
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:
EndpointEvent::Discovery(..)viawaitorpoll
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:
EndpointEvent::Discovery(..), plusEndpointEvent::MdnsFailed { error }/MdnsRecoveredfor socket failures, viawaitorpoll - mDNS lifecycle:
shutdownsends goodbyes and stops mDNS without closing the endpoint, returningResult<(), MdnsError>
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. A socket failure while running does not stop mDNS: it is reported as MdnsFailed, retried after MDNS_FAILURE_RETRY (100 ms), and followed by MdnsRecovered once a retry works. 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 listen (complete multiaddresses) and protocols |
Minip2p.create starts the endpoint; without listen it binds 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 for configuration examples, and the TypeScript API reference for the full configuration map.
Full Rust API
docs.rs publishes the Rust API for the latest release. That reference uses the default std and quic features. Check the published feature list for the optional flags.
Generate the default rustdoc locally:
cargo doc -p minip2p-rs --no-deps --open
To include every optional std feature in one local build:
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:
cargo doc -p minip2p-rs --no-default-features --features smoltcp,pubsub,portable-autonat,portable-relay --no-deps --open