Nostr SDK

A full-featured Rust SDK for building high-performance clients and in-process relays on the Nostr protocol

SDK
Cargo
v0.45.1
666stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
82/100Excellent
Development Activity100
Maintenance52
Community84
Maturity52
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
80/100Excellent
Architecture82
Code Quality78
Innovation80
Learning Curve78

Nostr SDK is the high-level Rust crate in the rust-nostr / Nostr Dev Kit workspace, built for building both sides of a Nostr application: clients, bots, and services that connect to existing relays, and local relays (including ephemeral mock relays for tests) that run inside your own process. It wraps the lower-level nostr protocol crate with a Client type that manages a relay connection pool, subscriptions, event streaming, NIP-65 gossip-based relay discovery, and outbox-model publishing, so applications don’t have to hand-roll WebSocket connection management or relay bookkeeping.

The crate is part of a larger Cargo workspace that splits protocol concerns into focused crates (nostr, nostr-database, nostr-connect, nostr-gossip, signer implementations, storage backends), and nostr-sdk composes them into a single ergonomic entrypoint via its prelude module. It targets both native and wasm32 builds, ships pluggable TLS/crypto backends (ring, aws-lc-rs, rustls, native-tls), and is used as the foundation for Nostr Wallet Connect (NIP-47), Nostr Connect (NIP-46) remote signing, and relay-backed application development across the Nostr ecosystem.

What You Get

  • A Client type with connection pooling across many relays, automatic reconnection, and per-relay read/write capability flags
  • Event publishing and subscription APIs, including streaming subscriptions and auto-closing one-shot fetches
  • Built-in gossip-model relay discovery (NIP-65) so events reach the right relays without manual relay-list management
  • An in-process LocalRelay and ephemeral MockRelay for running a fully-fledged or test-only relay inside your own process
  • NIP-77 negentropy-based sync for efficient event set reconciliation between client and relay
  • Pluggable TLS/crypto backends (ring, aws-lc-rs, rustls with webpki or native roots, native-tls) and SOCKS/Tor proxy support
  • A prelude module that re-exports the whole workspace (nostr, nostr-database, signers, gossip) for a single-import developer experience

Common Use Cases

  • Building a Nostr client application (bot, feed reader, social app) that connects to public relays and publishes/reads events
  • Building a Nostr Wallet Connect (NIP-47) or Nostr Connect (NIP-46) remote-signing integration
  • Running an embedded or test-only relay inside a Rust process without deploying a separate relay server
  • Implementing relay-aware applications that need gossip-based (NIP-65) discovery instead of hardcoded relay lists
  • Writing integration tests for Nostr-aware code using the ephemeral MockRelay instead of a live network relay

Under The Hood

Architecture — The crate is organized around three cooperating layers traced from src/lib.rs: client/mod.rs exposes the public Client/ClientBuilder API and owns gossip-based relay resolution (client/gossip/); pool/mod.rs implements RelayPool, a non-cloneable struct guarded by a Drop impl that shuts down all relay connections on first drop (RwLock<HashMap<RelayUrl, Relay>> plus a broadcast notification channel); and relay/mod.rs implements per-relay connection state (relay/inner.rs, relay/api/) with its own status, stats, ping, and capability tracking. A separate local_relay/ module implements LocalRelay and MockRelay, in-process relay servers built on the same nostr-database/nostr-gossip trait abstractions used by the client side, letting a process act as client and relay simultaneously (used for embedded and test scenarios).

Tech Stack — Pure Rust on the 2024 edition, built on tokio (with wasm32 compatibility maintained separately), futures for stream combinators, and async-wsocket for the underlying WebSocket transport (feature-gated across ring/aws-lc-rs/rustls/native-tls TLS backends). It depends on sibling workspace crates (nostr, nostr-database, nostr-gossip, optionally nostr-memory) rather than vendoring protocol logic, and uses opaquerr for structured error kinds, lru for caching, and negentropy for NIP-77 set reconciliation.

Code Quality — Tests are distributed inline across the crate rather than centralized: #[test]/#[tokio::test] blocks appear in roughly 30 of the ~40 source files (e.g. relay/capabilities.rs, relay/mod.rs, local_relay/local/mod.rs, client/gossip/semaphore.rs), covering capability parsing, relay status transitions, and gossip resolution logic. The crate forbids unsafe_code and warns on missing_docs at the crate root (#![forbid(unsafe_code)], #![warn(missing_docs)]), and errors are modeled through a single opaquerr-defined Error/ErrorKind enum (error.rs) with explicit From conversions from every dependency error type rather than ad hoc unwrap()/string errors.

API Design — The prelude::* glob import pattern (used in every example) collapses the whole multi-crate workspace into one import, and the builder pattern (Client::builder(), LocalRelay::builder()) keeps construction ergonomic despite many optional knobs (proxy, gossip, relay limits, TLS backend). Getting started is genuinely minimal — Client::new(), add_relay(), connect(), send_event() — as shown in examples/client.rs, though the crate is explicit in its README that it is in an ALPHA state and the API can still change in breaking ways between releases.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search