What is Nostr? The Decentralized Protocol for Developers
The Flip: A Developer's First Look at Nostr, the Protocol That Inverts the Client-Server World

This is Part 1 of a two-part series. Part 2 covers the real-world challenges of building production applications on Nostr.

When our team joined the diVine project—a decentralized short-form video app—we thought we knew how to build networked applications. Then Nostr asked us to rethink what a server even does.
Smart Clients, Dumb Servers
Most architectures you’ve shipped follow a familiar pattern: the server is the brain. It authenticates users, stores data, enforces business logic, resolves conflicts, and decides what each client sees. The client renders what it is told.
Nostr inverts this. The relay—Nostr’s version of a server—is intentionally simple. It accepts events, stores them, and forwards them to subscribers. The relay does not resolve conflicts between data versions and does not decide what a client should see. Some relays support authentication, but by default there is no login — the relay is a pipe with a filter.
The client, by contrast, does all the heavy lifting. It generates and manages cryptographic keys, decides which relays to connect to, assembles a coherent view of the world from multiple relay responses, handles data reconciliation when relays disagree, and manages the user’s social graph locally. In Nostr, the intelligence lives on the device.
This is the single most important thing to understand before writing a line of Nostr code. If you come from a traditional backend mindset where the server is authoritative, you will need to shift your mental model. The client is not a thin layer over an API—it is the application.
That architectural inversion starts with the most fundamental question: who are you on the network?

Identity Without Accounts
On Nostr, your identity is your key pair. Your public key is your username. Your private key proves you are you. No registration step, no email verification, no username collision. Most Nostr clients generate this key pair for you on first launch and store it locally unless you choose to export or back it up. Under the hood, keys use secp256k1 (the same elliptic curve Bitcoin uses) and are encoded as npub/nsec strings via NIP-19.
That means identity is portable. Your key pair works on any Nostr client, on any relay, forever. Nobody can deplatform you by deleting your account because there is no account to delete. Your identity exists independently of any infrastructure.
Nothing prevents a single person from creating multiple key pairs. Some users operate several identities: a public persona, an anonymous account, one for experimentation, one for a project or organization. Because keys are cheap to generate and require no registration, identity on Nostr is fluid and composable rather than singular and fixed.
It is also unforgiving. There is no “forgot password” flow. If you lose your private key, your identity is gone. If someone gains access to your private key, they can impersonate you and there is no authority to appeal to.
The ecosystem has responded with tools that soften this edge. Browser extension signers keep your private key secure rather than pasted into every client. Mobile signer apps do the same, letting applications request signatures without ever touching the raw key. These tools do not eliminate the trade-off between self-sovereignty and user safety—they shift where the trust boundary sits. We dig into these trade-offs in Part 2.

Events: The Only Data Type
In most protocols, you deal with multiple object types: users, posts, messages, reactions, and profiles. Nostr has exactly one: the event. Every piece of data on the network is a JSON object with the same fields—an identifier, the author’s public key, a timestamp, a kind integer that tells clients how to interpret it, a tags array for references and metadata, a content string, and a cryptographic signature proving the author wrote it.
That is the entire data model. A profile update, a text post, a follow list, a direct message, and a video event all share this exact structure. What differs is the kind number and how clients interpret content and tags. This uniformity means relays do not need to understand what they are storing—a relay built for text notes will happily forward video events without any code changes.

How Events Move: Relays And WebSockets
Anyone can run a relay. There is no central registry or approval process. Some relays are public and free to use, while others are private, community-run, invite-only, or charge fees. Relay operators choose what events they will accept, how long they will store them, and what moderation policies they enforce.
A client connects to one or more relays and communicates using a simple JSON message protocol defined in NIP-01, the foundational specification.
The client can do three things:
- Publish — send a signed event to the relay for storage and distribution
- Subscribe — request events matching a filter (by author, by kind, by tag, by time range)
- Close — end a subscription
No endpoints for user registration, no authentication tokens, no rate-limit headers (though relays may enforce their own limits). The relay either accepts your event or it does not.
A critical design choice: relays generally do not talk to each other. The protocol defines no gossip layer, no consensus mechanism, no peer-to-peer relay mesh. Some relay implementations do sync with each other, but this is not common and not something clients can rely on. In practice, if you publish an event to Relay A, you should assume Relay B does not have it unless a client also sends it there.

NIPs and Event Kinds
Rather than a top-down standards body, Nostr evolves through NIPs—Nostr Implementation Possibilities. Each NIP proposes a convention for how clients and relays handle specific use cases. The kind integer in every event is what makes this work: kind 0 is user metadata, kind 1 is a text note, kind 3 is a follow list, kind 10002 is relay list metadata. Different kinds, same event structure, same relays.
A few NIPs to know when starting out: NIP-01 defines the core protocol flow, NIP-19 gives you the human-readable encodings (npub, nsec, nevent), and NIP-65 defines how users advertise which relays they use—the backbone of relay discovery. NIP-55 and NIP-07 cover signer app integration for keeping private keys off devices running untrusted client code.
The NIP system is what makes Nostr extensible without coordination. Because event kinds are just integers and relays forward events they do not understand, new functionality can be added without upgrading the network. When the diVine project needed to handle video events, we chose a kind range, documented the content structure, and shipped. No relay upgrades required.

The Event Lifecycle
A user generates a key pair locally—their public key is now their identity on the network. They compose a text note, and their client creates a kind 1 event, populates the fields, and signs it with the private key. The client then publishes the signed event to the user’s preferred relays (advertised in their relay list event). Another user’s client, subscribed to events from that public key, receives the event from one of those relays. It verifies the Schnorr signature, confirms the event has not been tampered with, and renders it.
No server decided these users could interact. No platform approved the content. No algorithm ranked it. The relay just moved bytes.

What This Means For Builders
The architecture has immediate practical implications:
Your client is the product. On traditional platforms, two clients using the same API look and feel roughly the same because the server shapes the experience. On Nostr, two clients connecting to the same relays can offer radically different experiences. The client decides what to show, how to rank it, which relays to trust, and how to handle conflicts. This is simultaneously more freedom and more responsibility.
Local state matters. Because relays can disagree and go offline, your client needs robust local persistence. You are building an eventually consistent system, not a request-response API consumer.
The hard problems are client-side. Key management, relay discovery, data reconciliation, spam filtering, content moderation—all of these are client responsibilities. Part 2 of this series is dedicated to these challenges because they are where the real engineering happens.
The ecosystem is interoperable. Anything your app publishes is visible to every other Nostr client. A user’s social graph, follows, and profile travel with them across apps. You do not need to build network effects from zero—you inherit them.
What Comes Next
Now you have the foundation: one data type, dumb relays, smart clients, and cryptographic identity. The protocol is small enough to hold in your head and flexible enough to build almost anything on top of. That combination is rare—and it is what makes Nostr worth taking seriously as an engineering decision, not just a philosophical one.
That flexibility comes at a cost. In Part 2, we get into what it is actually like to build on Nostr: the relay discovery problem, the key management UX wall, data consistency across relays, and the trade-offs we encountered working on diVine. That is where the protocol’s elegance collides with real-world complexity.