How Nostr works
The name stands for “Notes and Other Stuff Transmitted by Relays”. The project README describes the idea simply: each person publishes notes to several relays, which are simple servers, and people who follow them connect to those relays to fetch the notes. Relays can be run by anyone, with whatever rules their operators choose. Because every note is signed, a relay can refuse to carry a note or lose it, but it cannot forge or alter one without the signature failing. The repository is released into the public domain.
NIP-01 defines the core. There is one object type, the event, with these fields:
id, the SHA-256 hash of the serialised eventpubkey, the author’s public keycreated_at, a Unix timestampkind, a number that tells clients how to interpret the eventtags, references to other events, keys and valuescontent, the payloadsig, a Schnorr signature over the id, on the secp256k1 curve
Kinds are grouped by convention. Regular events are expected to be stored by relays, replaceable events keep only the latest version per author and kind, and ephemeral events are not expected to be stored at all.
Clients and relays
Relays expose a WebSocket endpoint, and NIP-01 says a client should open one connection per relay and use it for all its subscriptions. A client sends three kinds of message: EVENT to publish, REQ to subscribe with one or more filters, and CLOSE to end a subscription. Filters can match on event ids, authors, kinds, tag values, and a time range. The relay answers with matching EVENTs, an EOSE marker at the end of stored events, OK to accept or reject a published event with a reason, CLOSED when it ends a subscription, and NOTICE for human-readable messages.
Relays decide what they accept. NIP-01’s examples include rejecting events from unregistered keys and events with implausible timestamps. Finding which relays hold a given person’s events is, in the README’s words, the hardest part, and clients use several heuristics to approach it.
NIPs
Everything beyond the basics lives in NIPs, Nostr Implementation Possibilities, kept in a public repository. The NIPs README is explicit that they are not a checklist: nothing forces software to implement any NIP, and each app picks the subset it needs. Some are marked unrecommended. NIP-04, the original encrypted direct message format, is deprecated in favour of NIP-17.
Private messages: NIP-44 and NIP-59
NIP-44 defines versioned encryption for payloads inside signed events. Version 2 uses secp256k1 ECDH, HKDF, padding, ChaCha20, HMAC-SHA256 and base64. The NIP lists its own limits plainly: no deniability, no forward secrecy, no post-compromise security, a user’s IP address possibly visible to relays, a public created_at, and padding that only partly hides message length. For high-risk situations it advises using specialised end-to-end encrypted messaging software.
NIP-59 adds gift wrapping to hide who sent what. The real event becomes an unsigned “rumor”. The rumor is encrypted into a “seal” signed by the author and addressed to nobody visible. The seal is then encrypted into a “gift wrap” signed by a random, one-time key and tagged with the recipient’s key so relays can route it. A relay sees the recipient tag and a throwaway signer, not the author or the content.
What Nostr is good for, and what it is not
Nostr gives an app a way to reach people anywhere without running its own messaging backend, as long as both sides can reach a common relay. That is also its limit: relays are servers on the internet, so Nostr needs a working network path. It does not replace a local radio when there is no network at all. Even with sealing, encryption hides content more than metadata: a relay sees connections, subscriptions, timing and volume.
Some apps pair it with a local link for that reason. Bitchat pairs a Bluetooth mesh with Nostr relays as its internet fallback, described in how to build an app like Bitchat. The Offline Protocol mesh SDK also lists Nostr as a transport. It is off by default in React Native and needs at least one reachable relay URL. In version 0.27.0 the SDK seals outgoing envelopes by default as NIP-59 gift wraps with NIP-44 encryption, and a relay still sees subscriptions, timing and traffic volume. Its cold contact setting, on by default, publishes key packages to relays so peers can make first contact.