Skip to content

Usage

Quick Start

A simple example of how to use NDK in a Node.js application:

ts
import NDK, {NDKEvent, NDKPrivateKeySigner} from "@nostr-dev-kit/ndk";

async function main() {
    const signer = NDKPrivateKeySigner.generate();
    const ndk = new NDK({
        explicitRelayUrls: ["wss://relay.primal.net"],
        signer,

        // ⚠️ STRONGLY RECOMMENDED: Enable during development
        // Catches common mistakes before they cause silent failures
        aiGuardrails: true,
    });

    // Connect to relays
    await ndk.connect();

    // Publish a simple text note
    const event = new NDKEvent(ndk, {
        kind: 1,
        content: "Hello Nostr via NDK!",
    });
    await event.sign();
    event.publish();

    // subscribe to all event interactions
    ndk.subscribe(
        event.filter(),
        {closeOnEose: false},
        {
            onEvent: (replyEvent: NDKEvent) =>
                console.log(replyEvent.author.npub, "interacted with our hello world with a kind", replyEvent.kind),
        },
    );

    // Subscribe to incoming text notes
    const subscription = ndk.subscribe(
        {kinds: [1]},
        {closeOnEose: true},
        {
            onEvent: (evt) => console.log("Received event:", evt),
            onEose: () => console.log("End of stream"),
        },
    );
}

main().catch(console.error);

NDK Usage

Instantiate NDK

You can pass an object with several options to a newly created instance of NDK.

ts
// Import the package
import NDK from "@nostr-dev-kit/ndk";

// Create a new NDK instance with explicit relays
const ndk = new NDK({
    explicitRelayUrls: ["wss://a.relay", "wss://another.relay"],
});

Note: In normal client use, it's best practice to instantiate NDK as a singleton class. See more below.

Connecting

After you've instantiated NDK, you need to tell it to connect before you'll be able to interact with any relays.

ts
// Import the package
import NDK from "@nostr-dev-kit/ndk";

// Create a new NDK instance with explicit relays
const ndk = new NDK({
    explicitRelayUrls: ["wss://a.relay", "wss://another.relay"],
});
// Now connect to specified relays
await ndk.connect();

Using NIP-19 Identifiers

NDK re-exports NIP-19 from the nostr-tools library which provides different utilities for encoding and decoding Nostr identifiers:

ts
import { nip19 } from "@nostr-dev-kit/ndk";

// Encode a pubkey as npub
const npub = nip19.npubEncode("3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d");
console.log(npub); //

// Decode any NIP-19 identifier
const decoded = nip19.decode("npub1...");
console.log(decoded.type); // "npub"
console.log(decoded.data); // hex pubkey

// Encode events
const nevent = nip19.neventEncode({
    id: "574033c986bea1d7493738b46fec1bb98dd6a826391d6aa893137e89790027ec",
    relays: ["wss://relay.example.com"],
    author: "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d",
});

console.log(nevent);

Managing Users

NDK provides flexible ways to fetch user objects, including support for NIP-19 encoded identifiers and NIP-05 addresses:

ts
import NDK from "@nostr-dev-kit/ndk";

const ndk = new NDK({});

// From hex pubkey
const user1 = await ndk.fetchUser("3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d");

// From npub (NIP-19 encoded)
const user2 = await ndk.fetchUser("npub1n0sturny6w9zn2wwexju3m6asu7zh7jnv2jt2kx6tlmfhs7thq0qnflahe");

// From nprofile (includes relay hints)
const user3 = await ndk.fetchUser(
    "nprofile1qqsrhuxx8l9ex335q7he0f09aej04zpazpl0ne2cgukyawd24mayt8gpp4mhxue69uhhytnc9e3k7mgpz4mhxue69uhkg6nzv9ejuumpv34kytnrdaksjlyr9p",
);

// From NIP-05 identifier
const user4 = await ndk.fetchUser("pablo@test.com");
const user5 = await ndk.fetchUser("test.com"); // Uses _@test.com

// The method automatically detects the format
const user6 = await ndk.fetchUser("deadbeef..."); // Assumes hex pubkey

Note: fetchUser is async and returns a Promise. For NIP-05 lookups, it may return undefined if the address cannot be resolved.

See the NIP-19 tutorial for comprehensive examples and use cases.

Framework Integrations

If you're planning to use NDK in a react framework, check out the documentation for these specific packages: