Configuration
Config File Relay Aliases
Help
FAQ

Introduction

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.

What is nostrito?

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.

Key Features

  • WoT-aware sync — only stores events from trusted pubkeys
  • Local NIP-01 relay — works with any Nostr client
  • Blossom media cache — images, videos, audio stored locally
  • Human-friendly config — relay aliases, TOML format
  • Offline-first — your data is always available
  • Single binary — no runtime deps, no Docker, no Node.js

How It Works

When you start nostrito for the first time, you provide your npub. nostrito then:

  1. Fetches your follow list (kind:3) from configured relays
  2. Computes your Web of Trust graph (configurable depth)
  3. Syncs events from trusted pubkeys
  4. Caches Blossom media locally
  5. Serves everything via a local WebSocket relay
💡 Tip: Point your Nostr client at ws://localhost:4869 and your feed will load from your local machine — even when you're offline.

Installation

nostrito ships as a single binary for macOS, Linux, and Windows. No dependencies required.

macOS

Download the latest .dmg from the GitHub Releases page, or install via Homebrew:

# Install via Homebrew brew install nostrito/tap/nostrito

Linux

Download the binary for your architecture (x86_64 or aarch64):

# Download and install curl -L https://github.com/nostrito/nostrito/releases/latest/download/nostrito-linux-x86_64 -o nostrito chmod +x nostrito sudo mv nostrito /usr/local/bin/

Windows

Download the .exe from the GitHub Releases page and add it to your PATH.

Build from Source

# Requires Rust 1.75+ git clone https://github.com/nostrito/nostrito.git cd nostrito cargo build --release

Quick Start

Get nostrito running in under a minute.

1. Start nostrito

Open the app (or run the binary). You'll be greeted with the setup wizard.

2. Enter your npub

Paste your Nostr public key. nostrito will set up the database and begin computing your Web of Trust.

3. Pick your relays

Select which relays to sync from. You can use friendly names — primal, damus, nos — instead of full WebSocket URLs.

4. Configure storage

Set how much space to allocate for others' events and media. Your own events are always stored at 100%.

5. Connect your client

Add ws://localhost:4869 to your Nostr client's relay list. Your feed will load from your local relay.

🎉 That's it! nostrito runs in the background, syncing your network and serving your feed locally.

Config File

nostrito uses a TOML configuration file at ~/.nostrito/config.toml.

Default Configuration

# ~/.nostrito/config.toml [identity] npub = "npub1..." [relay] port = 4869 bind = "127.0.0.1" [sync] relays = ["primal", "damus", "nos"] interval_secs = 300 [wot] max_depth = 3 refresh_hours = 6 [storage.own] enabled = true # always true, can't disable [storage.others] events_quota_gb = 5 media_quota_gb = 2 wot_depth = 2 cleanup = "oldest" # or "least_interacted"

Environment Variables

Any config value can be overridden with environment variables using the NOSTRITO_ prefix:

NOSTRITO_RELAY_PORT=4870 nostrito

Relay Aliases

You never have to type a wss:// URL. nostrito uses friendly names for every relay, and handles the mapping internally.

Why aliases?

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.

Built-in aliases

nostrito ships with 8 built-in aliases covering the most popular Nostr relays:

AliasResolves toDescription
primalwss://relay.primal.netPopular social relay with fast global coverage
damuswss://relay.damus.ioiOS-first community, one of the largest relays
noswss://relay.nos.socialOpen social network relay
snortwss://relay.snort.socialWeb client relay, popular with browser users
coraclewss://relay.coracle.socialPrivacy-focused, good for discovery
nostr.winewss://nostr.wineCurated content, paid relay with quality filtering
amethystwss://nostr.bandAndroid community relay and search index
yakihonnewss://relay.yakihonne.comLong-form content and articles

How resolution works

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.

💡 Tip: In the setup wizard, you just toggle relay names on and off. nostrito resolves them to real URLs behind the scenes. You can mix aliases and raw URLs freely in the config file.

Custom aliases

Add your own aliases in the config file. Useful for private relays or relays that aren't in the built-in list:

[aliases] myrelay = "wss://relay.example.com" work = "wss://internal-relay.company.io"

Custom aliases work exactly like built-in ones — use them anywhere you'd use a relay name.

Storage

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.

Your events — always 100%

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.

Others' events — quota-based

Events from people in your Web of Trust are stored up to the quota you set during setup. You configure two separate limits:

  • Events quota — how many GB to allocate for text events (notes, replies, reactions, etc.) from others
  • Media quota — how many GB to allocate for Blossom media (images, videos, audio) from others

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.

Blossom media verification

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.

Auto-cleanup

When either quota fills up, nostrito automatically makes room using your chosen strategy:

  • Oldest first — deletes the oldest events and media first. Simple and predictable.
  • Least interacted — keeps events you've engaged with (replied to, reacted to, zapped) and removes the ones you haven't. Smarter, but slightly more complex.

Cleanup never touches your own events. Only others' data is subject to quota limits.

WoT-aware storage priority

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.

Database

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.

Web of Trust

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.

The core idea

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.

How the graph is built

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.

BFS algorithm

nostrito uses breadth-first search (BFS) to compute trust distances. Starting from your pubkey, it explores the graph layer by layer:

  1. Layer 0: You. Trust distance = 0.
  2. Layer 1: Everyone in your follow list. Trust distance = 1.
  3. Layer 2: Everyone followed by layer-1 contacts (who isn't already in layer 0 or 1). Trust distance = 2.
  4. Layer 3: Same pattern, one more hop out. Trust distance = 3.

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.

Trust scoring

Distance alone isn't the whole picture. nostrito also factors in:

  • Follower count from your WoT — if many of your follows also follow someone, that person is more trusted than someone reached by a single chain
  • Mutual follows — bidirectional follow relationships carry more weight than one-way follows
  • Bridge nodes — nostrito can identify which contacts act as "bridges" connecting you to a distant pubkey

Hop depths in practice

DepthWho's includedTypical sizeTrust level
1-hopPeople you directly follow50–500 pubkeysHigh — you chose to follow them
2-hopPeople your follows follow5,000–50,000 pubkeysMedium — vouched for by someone you trust
3-hopOne more degree out100,000+ pubkeysLow — useful for spam filtering, not for curation
💡 Why 3 hops max? Beyond 3 hops, the graph expands so rapidly that nearly everyone on Nostr is included. At that point, trust distance stops being meaningful. nostrito defaults to 3 but you can lower it to 2 or 1 if you want a tighter circle.

Configuration

[wot] max_depth = 3 # how many hops to compute (1, 2, or 3) refresh_hours = 6 # how often to re-crawl follow lists

Storage integration

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:

[storage.others] wot_depth = 2 # store events up to 2 hops away depth_1_kinds = "all" # everything from direct follows depth_2_kinds = [1] # only notes (kind:1) from 2-hop contacts

Events from pubkeys outside your configured WoT depth are silently dropped — they never touch your database.

Sync Engine

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.

The 4-tier system

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:

Tier 1 — Critical (completes in seconds)

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.

Tier 2 — Important (completes in minutes)

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.

Tier 3 — Background (completes in hours)

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.

Tier 4 — Archive (completes in days)

The lowest priority tier handles everything else:

  • Blossom media downloads — images, videos, and audio from events nostrito has already stored
  • Historical events — notes older than 7 days from your follows
  • Deep WoT — 3-hop+ pubkeys, if configured

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.

💡 Why tiers? Most relay apps try to fetch everything at once, which overwhelms relays and makes the app feel slow on first launch. nostrito's tiered approach means your feed is usable in seconds, even while the full graph takes hours to build.

Politeness policies

nostrito is designed to be a good citizen on the Nostr network. It never floods relays with requests.

Rate limiting

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.

Exponential backoff

When a relay connection fails, nostrito doesn't retry immediately. It backs off exponentially:

  • 1st failure: wait 5 seconds
  • 2nd failure: wait 10 seconds
  • 3rd failure: wait 30 seconds
  • 4th failure: wait 60 seconds
  • 5th failure: wait 120 seconds
  • Maximum: 300 seconds (5 minutes)

The backoff resets after a successful connection. This prevents nostrito from hammering a relay that's temporarily down.

The since filter — never re-fetch old events

After 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.

Primary relay

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.

Sync progress

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.

Surviving restarts

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.

Blossom Media

nostrito automatically caches media from Blossom URLs, verified by hash.

What is Blossom?

Blossom is a content-addressed media hosting protocol for Nostr. Files are referenced by their SHA-256 hash, making them verifiable and portable.

How nostrito handles media

When nostrito encounters a Blossom URL in an event, it:

  1. Downloads the file to ~/.nostrito/blossom/
  2. Verifies the SHA-256 hash matches
  3. Serves it locally when clients request it

Configuration

[blossom] enabled = true images = true videos = true audio = true max_file_size_mb = 100

Advanced Configuration

Fine-tune nostrito's behavior for power users.

Daemon Mode

nostrito can run as a background daemon, starting automatically on login:

# macOS: install as LaunchAgent nostrito daemon install # Linux: install as systemd service nostrito daemon install --systemd # Manual start nostrito daemon start

Database Maintenance

Compact the database to reclaim space:

nostrito db compact nostrito db stats

Debug Logging

# Enable verbose logging NOSTRITO_LOG=debug nostrito # Or in config [logging] level = "debug"

Network Configuration

[network] timeout_secs = 10 max_connections = 8 proxy = "socks5://127.0.0.1:9050" # Tor support

Relay API

nostrito implements NIP-01 and additional NIPs for local relay functionality.

Supported NIPs

NIPDescriptionStatus
NIP-01Basic protocol flow✅ Full
NIP-02Follow List✅ Full
NIP-09Event Deletion✅ Full
NIP-11Relay Information✅ Full
NIP-45Counting results🔜 Planned

Connecting

Connect any NIP-01 compatible client to:

ws://localhost:4869

FAQ

Frequently asked questions about nostrito.

Is nostrito a full relay?

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.

Does nostrito work offline?

Yes! Once your events are synced, they're stored locally. Your Nostr client can read from nostrito even without an internet connection.

How much storage does it use?

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.

Can I use it alongside other relays?

Absolutely. Add nostrito as one of your client's relays. It complements public relays by providing fast local access and offline capability.

Is my data encrypted?

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.

How do I back up my data?

Copy the ~/.nostrito/ directory. It contains the database and all cached media.

Can I run it on a server?

Yes, but nostrito is designed as a personal relay. If you want to expose it externally, consider using a reverse proxy with authentication.