Overview
Every Nym integration sends its traffic through the mixnet via a Nym client. Which crate or package you use comes down to two questions:
- Runtime: where does your code run?
- Approach: do you control both sides of the connection (end-to-end), are you reaching a third-party service through the mixnet (proxy), or are you the service others reach over Nym (service provider)?
The table below maps those two answers to a package. It covers the first two approaches: a service provider is the end-to-end tooling on the server side, and building a Nym service provider covers it.
The decisions come in order:
- Does the workload fit? What Nym cannot do rules the mixnet in or out while doing so is still cheap.
- What are you defending against? Choose a defence turns your threat model into a network configuration. For a wallet, a messaging app or web browsing, that work is already done.
- Pick a package. The matrix below maps your runtime and approach to a crate or package.
- Decide what to route. Planning an integration works through it endpoint by endpoint. In a browser or WebView, routing a browser or WebView app has the mechanics.
Choosing a package
| Runtime | End-to-end (both sides run Nym) | Proxy (exit to clearnet) |
|---|---|---|
| Native Rust (desktop / CLI / server) | nym-sdk: Mixnet, Stream, Client Pool | smolmix: TcpStream / UdpSocket · nym-sdk SOCKS5 · nym-smoldvpn: WireGuard dVPN for bulk data, non-mixnet |
| Browser / WebView (JS + WASM) | TypeScript SDK: @nymproject/sdk raw messaging | mix-fetch HTTP/S · mix-dns DNS · mix-websocket WS/WSS |
Mobile is a host, not a runtime. The same phone can run either row. Compile the Rust SDK to a native library (uniffi plus cargo-swift (opens in a new tab) for an iOS XCFramework, or cargo-ndk (opens in a new tab) for Android jniLibs/), or load the WASM packages inside a WebView (Capacitor, Cordova, Ionic, WKWebView, Android WebView). The SDK ships FFI bindings for Go and C/C++ only; for Swift or Kotlin you generate your own from the sdk/ffi/shared (opens in a new tab) uniffi crate. The WebView path needs no Nym-specific native code. On Android the native path has a TLS bootstrap gotcha.
Throughput over the mixnet, threat model permitting. For bulk data, nym-smoldvpn tunnels your tokio traffic over a userspace WireGuard dVPN instead. What Nym cannot do covers what that trade gives up.
End-to-end or proxy
The runtime axis is about where your code runs: a native process has raw sockets and a filesystem, so it runs the full Rust client; a browser or WebView has neither (only WebSockets and fetch, under mixed-content rules), so it runs a WASM client inside a Web Worker. The approach axis is about who runs Nym at the other end.
End-to-end: both sides run a Nym client. Traffic stays Sphinx-encrypted the whole way, so there is no Exit Gateway, no clearnet hop, and no third-party server that learns your IP (threat-model assessment). Use it for peer-to-peer setups or anywhere you control both endpoints.
Proxy: only your side runs Nym. Traffic exits the mixnet at an Exit Gateway and continues to the destination over the public internet. The mixnet anonymises the sender; protecting the payload (TLS, Noise) is your application's job, exactly as on a direct connection. Use it for third-party services such as blockchain RPCs or external APIs.
dVPN proxy: for bulk data, nym-smoldvpn is a faster proxy that tunnels over a 2-hop WireGuard dVPN instead of the mixnet. It hides the client IP at line rate but drops the mixnet's timing protection, so choose it only where that trade suits your threat model.
Native only. nym-smoldvpn has no WebAssembly build, so the dVPN option in the matrix above has no browser equivalent. Its WireGuard datapath (boringtun) and userspace IP stack are built on tokio's networking and multi-threaded runtime, which pull in mio and do not compile for wasm32-unknown-unknown. In a browser or WebView, the mixnet-based mix-* packages are the only option.
Past the Exit Gateway, traffic travels the public internet like any other connection. The mixnet anonymises the sender but does not encrypt the payload beyond the gateway. Use TLS or another application-layer cipher. See Exit Gateway Services for what the exit can and cannot observe, and Exit security for which exit your package uses.
In a browser or WebView, your app talks to that WASM client through JS bindings rather than direct calls. The mixnet behaviour is identical in both modes, only the integration shape differs. See mix-* architecture for the full picture.
Packages
Rust
| Crate | Use it for |
|---|---|
nym-sdk | End-to-end mixnet messaging, AsyncRead/AsyncWrite byte streams, client pooling. Start with the Tour. |
smolmix | TcpStream and UdpSocket over the mixnet via a userspace IP stack. Compatible with tokio-rustls, hyper, tokio-tungstenite, and the rest of the async Rust ecosystem. |
nym-smoldvpn | A userspace 1-/2-hop WireGuard dVPN datapath. Tunnels tokio TcpStream, UdpSocket and gRPC/HTTP traffic to clearnet via the exit gateway, with an optional QUIC bridge for DPI-blocked clients. |
TypeScript
The four mix-* packages share one tunnel (mix-tunnel) and one WASM instance; install only what you need. See mix-* architecture for how they're wired.
| Package | Use it for |
|---|---|
mix-tunnel | The shared tunnel the three feature packages build on. Most apps don't import it directly. |
mix-fetch | Drop-in fetch() for HTTP and HTTPS through the mixnet. |
mix-dns | Hostname-to-IP resolution through the mixnet. UDP DNS via the IPR. |
mix-websocket | WebSocket-like class for WS and WSS through the mixnet. |
| TypeScript SDK | @nymproject/sdk: end-to-end raw messaging when you control both ends. Smart contracts via @nymproject/contract-clients. |
Standalone and other
| Resource | Use it for |
|---|---|
| Standalone clients | SOCKS5, WebSocket, and WebAssembly clients: pipe traffic through the mixnet without embedding an SDK. |
| Chain interaction | Query Nyx state, submit transactions, call Nym smart contracts. |
| APIs | Auto-generated reference for Nym infrastructure HTTP endpoints. |