# Basic Pub/Sub (/sdks/nodejs/tutorials/basic-pubsub)



## Overview [#overview]

This tutorial builds the "hello world" of KubeMQ messaging: a publisher and a subscriber talking over the **Events** pattern. Events are fire-and-forget — the broker fans a message out to every subscriber currently listening on the channel and moves on. There's no persistence, no acknowledgment, and no replay, which makes this the pattern to reach for when you need low-latency, high-throughput broadcast (metrics ticks, live status updates, cache-invalidation signals) and can tolerate losing a message if nobody is listening at the moment it's sent.

You'll wire up `subscribeToEvents()` with an `onEvent` callback, give the subscription a moment to register with the server, then call `sendEvent()` with a message built by `createEventMessage()`. Every connected subscriber on the channel gets its own copy, as opposed to a consumer group where only one member would receive it. &#x2A;*Gotchas:** if the subscriber isn't fully established before you publish, the event is simply gone — there's no queue catching it, which is why the sample waits on a `setTimeout` before sending; and because delivery isn't acknowledged, a crashed or disconnected subscriber never knows it missed anything.

## Prerequisites [#prerequisites]

* KubeMQ server running on `localhost:50000`
* Node.js SDK installed (`npm install kubemq-js`)

## Code [#code]

```typescript title="basic-pubsub.ts"
/**
 * Example: Basic Event Publish/Subscribe
 *
 * Demonstrates fire-and-forget event messaging where a publisher sends
 * events to a channel and one or more subscribers receive them.
 * Events are not persisted — subscribers must be connected to receive them.
 *
 * Prerequisites:
 *   - KubeMQ server running on localhost:50000
 *
 * Run: npx tsx examples/events/basic-pubsub.ts
 */
import { KubeMQClient, createEventMessage } from 'kubemq-js';

async function main(): Promise<void> {
  // TODO: Replace with your KubeMQ server address
  const client = await KubeMQClient.create({
    address: 'localhost:50000',
    clientId: 'js-events-basic-pubsub-client',
  });

  try {
    const subscription = client.subscribeToEvents({
      channel: 'js-events.basic-pubsub',
      onEvent: (event) => {
        console.log('Received event:', new TextDecoder().decode(event.body));
        console.log('  Channel:', event.channel);
        console.log('  Timestamp:', event.timestamp);
      },
      onError: (err) => {
        console.error('Subscription error:', err.message);
      },
    });

    // Allow subscription to fully establish on the server.
    await new Promise((resolve) => setTimeout(resolve, 1000));

    await client.sendEvent(
      createEventMessage({
        channel: 'js-events.basic-pubsub',
        body: 'New user registered: alice@example.com',
        metadata: 'signup-service',
        tags: { source: 'registration-api', priority: 'normal' },
      }),
    );

    console.log('Event published successfully');

    // Allow time for the subscriber to receive the message.
    await new Promise((resolve) => setTimeout(resolve, 1000));

    subscription.cancel();
  } finally {
    await client.close();
  }
}

main().catch(console.error);

// Expected output:
// Received event: New user registered: alice@example.com
//   Channel: js-events.basic-pubsub
//   Timestamp: <timestamp>
// Event published successfully

```

## How It Works [#how-it-works]

* `KubeMQClient.create()` establishes a persistent gRPC connection and returns a client ready for messaging.
* `subscribeToEvents()` registers a callback-based listener on the channel; the subscription handle's `cancel()` method tears it down cleanly.
* The 1-second `setTimeout` lets the gRPC stream register on the server before the publisher sends — without it the event may arrive before the subscriber is ready.
* `createEventMessage()` builds an immutable message object; `sendEvent()` fires it without waiting for acknowledgment (fire-and-forget semantics).

## Related [#related]

* [Pattern overview](/learn/events/getting-started)
* [Node.js SDK Reference](/sdks/nodejs/reference)
* [Cancel Subscription](/sdks/nodejs/how-to/events/cancel-subscription)
* [Consumer Group](/sdks/nodejs/how-to/events/consumer-group)
