nostrito is a personal Nostr mini-relay that runs on your machine. It builds your Web of Trust, syncs your feed, and caches your media — all locally.
nostrito is a lightweight, single-binary relay daemon written in Rust. It connects to the Nostr network, computes your Web of Trust from your follow list, and stores only the events and media from people you trust.
Your favorite Nostr client (Damus, Amethyst, Coracle, etc.) connects to nostrito over a local WebSocket, so your feed loads instantly — no network latency, no downtime, no dependency on third-party infrastructure.
When you start nostrito for the first time, you provide your npub. nostrito then:
ws://localhost:4869 and your feed will load from your local machine — even when you're offline.
nostrito ships as a single binary for macOS, Linux, and Windows. No dependencies required.
Download the latest .dmg from the GitHub Releases page, or install via Homebrew:
Download the binary for your architecture (x86_64 or aarch64):
Download the .exe from the GitHub Releases page and add it to your PATH.
Get nostrito running in under a minute.
Open the app (or run the binary). You'll be greeted with the setup wizard.
Paste your Nostr public key. nostrito will set up the database and begin computing your Web of Trust.
Select which relays to sync from. You can use friendly names — primal, damus, nos — instead of full WebSocket URLs.
Set how much space to allocate for others' events and media. Your own events are always stored at 100%.
Add ws://localhost:4869 to your Nostr client's relay list. Your feed will load from your local relay.
nostrito uses a TOML configuration file at ~/.nostrito/config.toml.
Any config value can be overridden with environment variables using the NOSTRITO_ prefix:
You never have to type a wss:// URL. nostrito uses friendly names for every relay, and handles the mapping internally.
WebSocket URLs are ugly and easy to mistype. nostrito lets you refer to relays by short, memorable names — in the setup wizard, in the config file, and everywhere else. When you pick "damus" during onboarding, nostrito knows that means wss://relay.damus.io. You never see the raw URL unless you go looking for it.
nostrito ships with 8 built-in aliases covering the most popular Nostr relays:
| Alias | Resolves to | Description |
|---|---|---|
primal | wss://relay.primal.net | Popular social relay with fast global coverage |
damus | wss://relay.damus.io | iOS-first community, one of the largest relays |
nos | wss://relay.nos.social | Open social network relay |
snort | wss://relay.snort.social | Web client relay, popular with browser users |
coracle | wss://relay.coracle.social | Privacy-focused, good for discovery |
nostr.wine | wss://nostr.wine | Curated content, paid relay with quality filtering |
amethyst | wss://nostr.band | Android community relay and search index |
yakihonne | wss://relay.yakihonne.com | Long-form content and articles |
When nostrito sees a relay name, it checks the alias table first. If the name matches a built-in alias, it uses the corresponding wss:// URL. If no alias matches, nostrito treats the name as a raw URL — so you can always use a full wss:// address if you need to connect to a relay that isn't in the alias list.
Add your own aliases in the config file. Useful for private relays or relays that aren't in the built-in list:
Custom aliases work exactly like built-in ones — use them anywhere you'd use a relay name.
nostrito gives you full control over what gets stored and how much disk space to use. Your data is always safe; everyone else's is quota-based.
Every event you've authored (notes, reactions, zaps, profile updates — everything) is stored permanently. So is any media you've posted via Blossom. This is non-negotiable: your data is yours, and nostrito never deletes it, no matter how tight storage gets.
This guarantee extends to all event kinds, all media types, and all time periods. If you wrote it, nostrito keeps it.
Events from people in your Web of Trust are stored up to the quota you set during setup. You configure two separate limits:
Within the media quota, you can toggle which types to cache: images, videos, and audio are each independently selectable. If you only care about images, turn off videos and audio to save space.
When nostrito downloads media from a Blossom URL, it doesn't just save the file blindly. Every download is verified against the SHA-256 hash embedded in the Blossom URL. If the hash doesn't match, the file is discarded. This prevents tampered or corrupted media from polluting your local cache.
Verified media is stored in ~/.nostrito/blossom/, organized by hash. When your Nostr client requests the file, nostrito serves it directly from disk — no network round-trip needed.
When either quota fills up, nostrito automatically makes room using your chosen strategy:
Cleanup never touches your own events. Only others' data is subject to quota limits.
Not all contacts are equal. Events from 1-hop contacts (people you directly follow) get storage priority over 2-hop or 3-hop contacts. When cleanup runs, it removes distant contacts' data first.
All event data lives in a single SQLite database at ~/.nostrito/data.db, using WAL mode for fast concurrent reads. Media files are stored separately in ~/.nostrito/blossom/. To back up everything, just copy the ~/.nostrito/ directory.
nostrito builds a trust graph from the Nostr network and uses it to decide which events to store, serve, and prioritize. No centralized authority — just math on follow lists.
On Nostr, every user publishes a follow list (a kind:3 event) that says "these are the people I follow." nostrito reads these lists and builds a graph of who trusts whom. The closer someone is to you in this graph, the more nostrito trusts them.
It starts with you. nostrito fetches your kind:3 event from a relay and extracts every pubkey you follow. Those are your 1-hop contacts — people you directly trust.
Then nostrito fetches the kind:3 events for each of your follows. The people they follow (but you don't) become your 2-hop contacts. One more round gives you 3-hop contacts.
The result is a directed graph with you at the center. nostrito stores this graph in memory for fast lookups and persists it to SQLite so it survives restarts.
nostrito uses breadth-first search (BFS) to compute trust distances. Starting from your pubkey, it explores the graph layer by layer:
BFS guarantees that the first time nostrito reaches a pubkey is via the shortest path, so the assigned trust distance is always the minimum number of hops from you.
Distance alone isn't the whole picture. nostrito also factors in:
| Depth | Who's included | Typical size | Trust level |
|---|---|---|---|
| 1-hop | People you directly follow | 50–500 pubkeys | High — you chose to follow them |
| 2-hop | People your follows follow | 5,000–50,000 pubkeys | Medium — vouched for by someone you trust |
| 3-hop | One more degree out | 100,000+ pubkeys | Low — useful for spam filtering, not for curation |
WoT depth directly controls what nostrito stores. You can set different policies per depth — for example, store all event types from 1-hop contacts but only short notes from 2-hop:
Events from pubkeys outside your configured WoT depth are silently dropped — they never touch your database.
nostrito syncs your data from the Nostr network using a 4-tier priority system. It fetches the most important things first, works its way through less urgent data in the background, and is always polite to the relays it connects to.
Not all data is equally urgent. When you first launch nostrito (or after a long time offline), it needs to fetch your profile, your follows, recent notes, and eventually the broader social graph. Instead of trying to do everything at once, nostrito works through four tiers in order:
The first thing nostrito does is fetch your own profile (kind:0 metadata) and your follow list (kind:3 contact list). This is a single request to one relay — fast and lightweight. Your follow list seeds the entire Web of Trust graph, so everything else depends on it.
Once tier 1 completes, nostrito knows who you follow. The app becomes usable immediately.
Now that nostrito knows your follow list, it fetches recent notes (kind:1 events) from your direct follows. It only looks at the last 7 days and caps at 500 events, so this stays fast.
Pubkeys are processed in batches of 20, with a short 300ms pause between batches to avoid hammering the relay. After tier 2, your feed is populated with recent content from the people you care about most.
This is the WoT crawl. For each person you follow, nostrito fetches their follow list (kind:3) to discover follows-of-follows. This builds out the 2-hop and 3-hop layers of your trust graph.
Tier 3 runs slowly on purpose — 10 pubkeys per batch with 2-second pauses between them. If you're actively using the app (scrolling your feed, interacting with the UI), tier 3 pauses entirely and resumes when you're idle. It also checkpoints its progress to the database, so if you quit and reopen nostrito, it picks up where it left off instead of starting over.
The lowest priority tier handles everything else:
Tier 4 only starts after tiers 1–3 are complete. It runs very slowly — 5 seconds between batches — and can take days to finish for a large social graph. That's fine. This is background work that fills in the gaps over time.
nostrito is designed to be a good citizen on the Nostr network. It never floods relays with requests.
By default, nostrito sends no more than 10 requests per minute to any single relay. If a relay sends a NOTICE message containing the words "rate" or "limit," nostrito immediately pauses all requests to that relay for 60 seconds.
When a relay connection fails, nostrito doesn't retry immediately. It backs off exponentially:
The backoff resets after a successful connection. This prevents nostrito from hammering a relay that's temporarily down.
since filter — never re-fetch old eventsAfter the initial sync, every subsequent request includes a since timestamp set to the most recent event nostrito has seen from that relay. This means nostrito only asks for new events — it never re-downloads data it already has. This dramatically reduces bandwidth and relay load over time.
The first relay in your configuration is treated as the primary relay. nostrito sends most of its requests there. Other relays are used as fallbacks — if the primary doesn't have what nostrito needs, it tries the others in order. This concentrates load on a single relay (which you presumably trust) rather than spreading requests across many.
nostrito emits real-time progress events as it syncs. The dashboard shows which tier is currently active, how many events have been fetched, and which relay is being queried. When a tier completes, the app updates automatically.
All sync progress is persisted to the database. If you quit nostrito mid-sync and reopen it later, it resumes from where it left off. Tier 3 in particular tracks exactly which pubkeys have been processed, so it doesn't re-crawl follow lists it's already seen.
nostrito automatically caches media from Blossom URLs, verified by hash.
Blossom is a content-addressed media hosting protocol for Nostr. Files are referenced by their SHA-256 hash, making them verifiable and portable.
When nostrito encounters a Blossom URL in an event, it:
~/.nostrito/blossom/Fine-tune nostrito's behavior for power users.
nostrito can run as a background daemon, starting automatically on login:
Compact the database to reclaim space:
nostrito implements NIP-01 and additional NIPs for local relay functionality.
| NIP | Description | Status |
|---|---|---|
NIP-01 | Basic protocol flow | ✅ Full |
NIP-02 | Follow List | ✅ Full |
NIP-09 | Event Deletion | ✅ Full |
NIP-11 | Relay Information | ✅ Full |
NIP-45 | Counting results | 🔜 Planned |
Connect any NIP-01 compatible client to:
Frequently asked questions about nostrito.
nostrito is a personal relay. It only accepts connections from localhost by default and only stores events from your Web of Trust. It's not designed to be a public relay.
Yes! Once your events are synced, they're stored locally. Your Nostr client can read from nostrito even without an internet connection.
That depends on your configuration. A typical setup with 2-hop WoT, 5 GB events quota, and 2 GB media quota uses about 2-5 GB total. Your own events are stored separately and don't count toward the quota.
Absolutely. Add nostrito as one of your client's relays. It complements public relays by providing fast local access and offline capability.
nostrito stores data in a SQLite database on your machine. The data itself is not encrypted at rest (since it's already public Nostr events), but your machine's full-disk encryption protects it.
Copy the ~/.nostrito/ directory. It contains the database and all cached media.
Yes, but nostrito is designed as a personal relay. If you want to expose it externally, consider using a reverse proxy with authentication.