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-dev-kit/messages

v2.0.0

Published

High-level messaging library for NDK supporting NIP-17 and NIP-EE

Readme

@nostr-dev-kit/messages

High-level messaging library for NDK that provides a unified API for private messaging protocols on Nostr.

Features

  • 🎯 Simple API - One-line message sending with automatic protocol handling
  • 🔐 NIP-17 Support - Gift-wrapped private messages with proper relay management
  • 💬 Conversation Management - Automatic grouping, threading, and read status
  • 📡 Event-Driven - Real-time updates via EventEmitter pattern
  • 💾 Storage Abstraction - Pluggable storage adapters for persistence
  • 🔄 Future-Proof - Ready for NIP-EE (MLS) when implemented

Installation

npm install @nostr-dev-kit/messages
# or
bun add @nostr-dev-kit/messages

Quick Start

import NDK from '@nostr-dev-kit/ndk';
import { NDKMessenger } from '@nostr-dev-kit/messages';

// Initialize NDK
const ndk = new NDK({
  explicitRelayUrls: ['wss://relay.damus.io'],
  signer: new NDKPrivateKeySigner(privateKey)
});
await ndk.connect();

// Create messenger
const messenger = new NDKMessenger(ndk);
await messenger.start();

// Send a message
const recipient = ndk.getUser({ npub: "npub1..." });
await messenger.sendMessage(recipient, "Hello!");

// Listen for messages
messenger.on('message', (message) => {
  console.log(`New message from ${message.sender.npub}: ${message.content}`);
});

API Reference

NDKMessenger

Main orchestrator class for messaging functionality.

class NDKMessenger extends EventEmitter {
  constructor(ndk: NDK, options?: MessengerOptions)

  // Start/stop the messenger
  async start(): Promise<void>
  stop(): void

  // Send messages
  async sendMessage(recipient: NDKUser, content: string): Promise<NDKMessage>

  // Manage conversations
  async getConversation(user: NDKUser): Promise<NDKConversation>
  async getConversations(): Promise<NDKConversation[]>

  // Publish relay preferences
  async publishDMRelays(relays: string[]): Promise<NDKEvent>
}

Events

  • message - New message received
  • conversation-created - New conversation started
  • error - Error occurred

NDKConversation

Represents a conversation between users with real-time updates.

class NDKConversation extends EventEmitter {
  readonly id: string
  readonly participants: NDKUser[]
  readonly protocol: 'nip17' | 'mls'

  // Send messages
  async sendMessage(content: string): Promise<NDKMessage>

  // Get messages
  async getMessages(limit?: number): Promise<NDKMessage[]>

  // Mark as read
  async markAsRead(): Promise<void>

  // Helpers
  getUnreadCount(): number
  getOtherParticipant(): NDKUser | undefined
  getLastMessage(): NDKMessage | undefined
}

Events

  • message - New message in conversation
  • state-change - Conversation state changed
  • error - Error in conversation

Storage Adapters

The library uses a storage adapter pattern for flexibility:

interface StorageAdapter {
  saveMessage(message: NDKMessage): Promise<void>
  getMessages(conversationId: string, limit?: number): Promise<NDKMessage[]>
  markAsRead(messageIds: string[]): Promise<void>
  getConversations(userId: string): Promise<ConversationMeta[]>
  saveConversation(conversation: ConversationMeta): Promise<void>
}

Built-in Adapters

  • MemoryAdapter - In-memory storage (default)
  • More adapters coming soon (Dexie, SQLite)

Examples

Basic Messaging

// Initialize
const messenger = new NDKMessenger(ndk);
await messenger.start();

// Send message
const bob = ndk.getUser({ npub: "npub1bob..." });
await messenger.sendMessage(bob, "Hey Bob!");

// Get conversation
const conversation = await messenger.getConversation(bob);
const messages = await conversation.getMessages();

// Mark as read
await conversation.markAsRead();

Real-time Updates

// Listen to all messages
messenger.on('message', (message) => {
  if (message.sender.pubkey !== messenger.myPubkey) {
    showNotification(`New message from ${message.sender.displayName}`);
  }
});

// Listen to specific conversation
conversation.on('message', (message) => {
  updateChatUI(message);
});

conversation.on('error', (error) => {
  console.error('Conversation error:', error);
});

Custom Storage

import { MemoryAdapter } from '@nostr-dev-kit/messages';

// Use custom storage
const messenger = new NDKMessenger(ndk, {
  storage: new MemoryAdapter(),
  autoStart: true
});

// Or implement your own
class MyStorageAdapter implements StorageAdapter {
  // ... implement interface methods
}

Cache Module Integration

This package supports NDK's cache module system for persistent storage:

import NDKCacheAdapterDexie from '@nostr-dev-kit/cache-dexie';
import { CacheModuleStorage, messagesCacheModule } from '@nostr-dev-kit/messages';

// Use with cache adapter that supports modules
const cacheAdapter = new NDKCacheAdapterDexie({ dbName: 'my-app' });

const ndk = new NDK({
  cacheAdapter,
  // ... other options
});

// Messages will automatically use cache if available
const messenger = new NDKMessenger(ndk, {
  storage: new CacheModuleStorage(cacheAdapter, userPubkey)
});

The messages cache module creates these collections:

  • messages - Individual messages with indexes for efficient querying
  • conversations - Conversation metadata and participants
  • mlsGroups - (Future) MLS group state
  • dmRelays - Relay preferences for DMs

Benefits:

  • Persistent Storage: Messages survive app restarts (IndexedDB in browser)
  • Automatic Migrations: Schema upgrades handled automatically
  • Type Safety: Fully typed collections and queries
  • Performance: Indexed fields for fast lookups

Relay Management

// Publish your DM relay preferences (kind 10050)
await messenger.publishDMRelays([
  'wss://relay.damus.io',
  'wss://nos.lol'
]);

NIP-17 Implementation

This library implements NIP-17 (Private Direct Messages) with:

  • Automatic rumor creation with proper pubkey setting
  • Gift wrapping with ephemeral keys
  • Relay discovery via kind 10050
  • Automatic subscription to kind 1059 events
  • Message deduplication

Future: NIP-EE Support

The library is designed to support NIP-EE (MLS-based messaging) when ready:

// Future API (same interface, different protocol)
const conversation = await messenger.createConversation([alice, bob, charlie]);
console.log(conversation.protocol); // 'mls' if all support it, 'nip17' otherwise

Development

# Install dependencies
bun install

# Build
bun run build

# Run tests
bun test

# Run example
cd examples/nip-17-chat
bunx tsx generate-keys.ts
bunx tsx src/index.ts

Contributing

Contributions are welcome! Please read our contributing guidelines before submitting PRs.

License

MIT

See Also