A collection of helper methods for storing nostr events in an IndexedDB and talking to it like a nostr relay
Live Examples: https://hzrd149.github.io/nostr-idb/
- Built directly on top of IndexedDB for the lowest latency
- Caches indexes in memory
NostrIDBclass with full nostr relay-like API
The NostrIDB class is the main interface for working with nostr events in IndexedDB. It provides a complete nostr relay-like API with automatic batching, caching, and subscription management.
import { NostrIDB, openDB } from "nostr-idb";
// Create a new NostrIDB instance
const db = await openDB("my-nostr-db");
const nostrDB = new NostrIDB(db);
// Start the database (starts background processes)
await nostrDB.start();
// Add events
await nostrDB.add(event1);
await nostrDB.add(event2);
// Query events
const subscription = nostrDB.subscribe([{ kinds: [1], limit: 10 }], {
event: (event) => console.log("New event:", event),
complete: () => console.log("Subscription complete"),
});
// Get a specific event
const event = await nostrDB.event("event-id");
// Count events matching filters
const count = await nostrDB.count([{ kinds: [1] }]);
// Stop the database
await nostrDB.stop();const nostrDB = new NostrIDB(db, {
batchWrite: 1000, // Number of events to batch before writing (default: 1000)
writeInterval: 100, // Write interval in ms (default: 100)
cacheIndexes: 1000, // Number of indexes to cache in memory (default: 1000)
pruneInterval: 60000, // How often to prune old events in ms (default: 60000)
maxEvents: 10000, // Maximum number of events to store (default: 10000)
});Add a single event to the database. Returns true if the event was added.
Get a single event by its ID.
Get the latest replaceable event for a given kind, author, and optional identifier.
Count the number of events matching the given filters.
Subscribe to events matching the filters. Returns a subscription object with a close() method.
Same as subscribe but automatically closes after EOSE (End of Stored Events).
Delete a single event by its ID.
Delete a replaceable event by pubkey, kind, and optional identifier.
Delete all events matching the given filters. Returns the number of deleted events.
Delete all events from the database.
Check which features the database supports.
// Batch add multiple events
const events = [event1, event2, event3];
for (const event of events) {
await nostrDB.add(event);
}
// Subscribe with error handling
const subscription = nostrDB.subscribe([{ kinds: [1] }], {
event: (event) => {
console.log("Received event:", event);
},
error: (error) => {
console.error("Subscription error:", error);
},
complete: () => {
console.log("Subscription completed");
},
});
// Clean up subscription
subscription.close();
// Query replaceable events
const profile = await nostrDB.replaceable(0, "pubkey");
const contactList = await nostrDB.replaceable(3, "pubkey", "contacts");
// Delete events by filters
const deletedCount = await nostrDB.deleteByFilters([
{ kinds: [1], authors: ["pubkey"] },
]);
console.log(`Deleted ${deletedCount} events`);NOTE: all methods are async unless specified otherwise
Opens a database with name and optional callbacks. see openDB
If no name is provided it will default to nostr-idb
import { openDB, NostrIDB } from "nostr-idb";
// Open the database
const db = await openDB("nostr-idb");
// Create a NostrIDB instance
const nostrDB = new NostrIDB(db);
await nostrDB.start();
// Use the NostrIDB instance
await nostrDB.add(event);Remove all events from the database without deleting it
Calls deleteDB from idb. see deleteDB
Returns a sorted array of events that match the filter/filters
import { openDB, NostrIDB } from "nostr-idb";
const db = await openDB("events");
const nostrDB = new NostrIDB(db);
await nostrDB.start();
// add events to db
await nostrDB.add(event1);
await nostrDB.add(event2);
// query db using subscription
const subscription = nostrDB.subscribe(
[
{
kinds: [1, 6],
limit: 30,
},
],
{
event: (event) => console.log("Found event:", event),
complete: () => console.log("Query complete"),
},
);Similar to getEventsForFilters but returns just the number of events
import { openDB, NostrIDB } from "nostr-idb";
const db = await openDB("events");
const nostrDB = new NostrIDB(db);
await nostrDB.start();
// count events matching filters
const count = await nostrDB.count([
{
kinds: [1, 6],
limit: 30,
},
]);
console.log(`Found ${count} events`);Add events to the database
The NostrIDB class automatically batches events for better performance. Use nostrDB.add(event) for individual events.
Removes the least used events until the database is under the size limit
The NostrIDB class automatically handles pruning based on the maxEvents option. You can also manually prune:
import { pruneLastUsed } from "nostr-idb";
// Manually prune to keep only 1000 events
await pruneLastUsed(db, 1000);