Your sovereign yearly recap on the Nostr protocol.
Nostr Rewind is a client-only Nostr application that generates a beautiful yearly recap of your activity across the Nostr relay network. Inspired by Spotify Wrapped, it distills your on-chain presence into an interactive, shareable story.
- 🔐 No backend, no database — relays are the source of truth
- ⚡ Client-side computation — your data stays with you
- 🎯 One-time generation — recap is computed and published once per year
- 🤖 AI-powered vibe analysis — get your unique identity title from LLMs
| Feature | Description |
|---|---|
| 🔑 Nostr Login | Authenticate via NIP-07 browser extensions (Alby, nos2x, etc.) or read-only pubkey mode |
| 📡 Relay-First Loading | Checks relays for existing recap before computing a new one |
| 📊 Client-Side Stats | Computes notes, replies, reactions, zaps, active days, and streaks locally |
| 🎭 AI Vibe Analysis | Uses Gemini/OpenRouter to generate a personalized identity title |
| 🎬 Interactive Slides | Beautiful, story-like presentation of your yearly stats |
| 📤 Share & Publish | publish your recap back to Nostr relays |
| 🖼️ Share Card | Generate your recap as an image |
flowchart LR
A[User Opens App] --> B{Existing Recap?}
B -->|Yes| C[Load from Relay]
B -->|No| D[Fetch Events]
D --> E[Compute Stats]
E --> F[Generate AI Vibe]
F --> G[Display Slides]
G --> H{Has Write Access?}
H -->|Yes| I[Publish to Relays]
H -->|No| J[View Only]
C --> G
- User authenticates via Nostr extension or enters a pubkey
- App queries relays for an existing recap event (Kind 30001)
- If found, the recap is parsed and displayed immediately
- If not found, the app fetches events (notes, reactions, zaps, follows) and computes stats
- AI generates a vibe — a personalized identity title based on your activity
- Interactive slides present your year in review
- publish the recap to relays for permanent storage
# Clone the repository
git clone https://github.com/theakash04/nostr-rewind.git
cd nostr-rewind
# Install dependencies
npm install
# Set up environment variables
cp .env.example .env
# Add your API keys to .envCreate a .env file with:
GEMINI_API=your_gemini_api_key
OPEN_ROUTER=your_openrouter_api_keyNote: The AI vibe feature requires at least one API key. If both fail, a default vibe is assigned.
# Start the development server
npm run devOpen http://localhost:3000 to see your app.
npm run build
npm start# Build and run with Docker
docker build -t nostr-rewind .
docker run -p 3000:3000 nostr-rewind
# Or use Docker Compose
docker compose upThe app connects to these high-uptime relays:
wss://nos.lol
wss://relay.damus.io
wss://relay.snort.social
wss://relay.primal.net
wss://relay.nostr.band
wss://nostr.bitcoiner.social
Recaps are stored as Kind 30001 (parameterized replaceable events):
{
"kind": 30001,
"pubkey": "<user_pubkey>",
"content": "<JSON stringified RecapData>",
"tags": [
["d", "nostr-recap:2025"],
["year", "2025"],
["client", "nostr-rewind"],
["schema", "v1"]
]
}interface RecapData {
pubkey: string;
totalNotes: number;
totalReplies: number;
totalReactions: number;
activeDays: number;
streak: number;
zapsCount: number;
totalSats: number;
newFollows: number;
topInteractions: {
name: string;
display_name: string;
picture: string;
count: number;
}[];
vibe: {
v: string; // Identity title (e.g., "Signal Builder")
desc: string; // Why you earned this title
};
}Contributions are welcome! Feel free to open issues or submit pull requests.
# Format code
npm run format
# Lint code
npm run lintMIT License — feel free to fork and build upon this project.
Made with 💜 by Sky on Nostr
2025 Nostr Retrospective • A Pure Protocol Experience
