npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

nostr-idb

v5.0.0

Published

A collection of helper methods for storing nostr events in IndexedDB

Readme

nostr-idb

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/

Features

  • Built directly on top of IndexedDB for the lowest latency
  • Caches indexes in memory
  • NostrIDB class with full nostr relay-like API

NostrIDB Class

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.

Basic Usage

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();

Configuration Options

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)
});

API Methods

add(event: NostrEvent): Promise<boolean>

Add a single event to the database. Returns true if the event was added.

event(id: string): Promise<NostrEvent | undefined>

Get a single event by its ID.

replaceable(kind: number, author: string, identifier?: string): Promise<NostrEvent | undefined>

Get the latest replaceable event for a given kind, author, and optional identifier.

count(filters: Filter[]): Promise<number>

Count the number of events matching the given filters.

subscribe(filters: Filter[], handlers: StreamHandlers): Subscription

Subscribe to events matching the filters. Returns a subscription object with a close() method.

filters(filters: Filter[]): Promise<NostrEvent[]>

Query events matching the given filters and return them as an array. This is a one-time query that returns all matching events.

deleteEvent(eventId: string): Promise<boolean>

Delete a single event by its ID.

deleteReplaceable(pubkey: string, kind: number, identifier?: string): Promise<boolean>

Delete a replaceable event by pubkey, kind, and optional identifier.

deleteByFilters(filters: Filter[]): Promise<number>

Delete all events matching the given filters. Returns the number of deleted events.

deleteAllEvents(): Promise<void>

Delete all events from the database.

supports(): Promise<Features[]>

Check which features the database supports.

Advanced Usage

// 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`);

Methods

NOTE: all methods are async unless specified otherwise

openDB

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);

clearDB

Remove all events from the database without deleting it

deleteDB

Calls deleteDB from idb. see deleteDB

getEventsForFilter / getEventsForFilters

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"),
  },
);

countEventsForFilter / countEventsForFilters

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`);

addEvent / addEvents

Add events to the database

The NostrIDB class automatically batches events for better performance. Use nostrDB.add(event) for individual events.

pruneDatabaseToSize(db, limit)

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);