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

@gibme/ssdp

v22.0.0

Published

A simple SSDP helper

Downloads

50

Readme

@gibme/ssdp

A lightweight SSDP (Simple Service Discovery Protocol) implementation for Node.js with full TypeScript support.

Requirements

  • Node.js >= 22

Installation

npm install @gibme/ssdp

or

yarn add @gibme/ssdp

Documentation

https://gibme-npm.github.io/ssdp

Features

Browser

Discover SSDP services on the network with automatic periodic searching.

  • Subscribes to specific service types and emits events on discovery or withdrawal
  • Dynamic subscription and unsubscription at runtime
  • Configurable search interval
  • Emits discover events for ssdp:alive, ssdp:update, and search replies
  • Emits withdraw events for ssdp:byebye notifications

Advertiser

Announce SSDP services on the network with automatic periodic notifications.

  • Automatically handles incoming M-SEARCH requests for:
    • upnp:rootdevice
    • uuid:<uuid>
    • ssdp:all
    • Any registered service types
  • Dynamic service announcement and withdrawal at runtime
  • Configurable notification interval
  • UUID v7 auto-generation for device identity
  • Optional authentication provider to control which hosts receive responses

Usage

Discovering Services

import { Browser } from '@gibme/ssdp';

const browser = await Browser.create({
    interval: 5_000,
    services: ['urn:schemas-upnp-org:device:MediaServer:1']
});

browser.on('discover', (service, payload, remote, local) => {
    console.log('Discovered:', { service, remote: remote.address });
});

browser.on('withdraw', (service, payload, remote, local) => {
    console.log('Withdrawn:', { service, remote: remote.address });
});

// Trigger an immediate search
browser.searchNow();

// Subscribe to additional services dynamically
browser.subscribe('urn:schemas-upnp-org:device:InternetGatewayDevice:1');

// Unsubscribe from a service
browser.unsubscribe('urn:schemas-upnp-org:device:MediaServer:1');

// Clean up when done
browser.destroy();

Advertising Services

import { Advertiser } from '@gibme/ssdp';

const advertiser = await Advertiser.create({
    interval: 5_000,
    services: {
        'urn:schemas-upnp-org:device:MediaServer:1': {
            'LOCATION': 'http://192.168.1.100:8080/description.xml'
        }
    }
});

// Announce a new service dynamically
advertiser.announce('urn:schemas-upnp-org:service:ContentDirectory:1', {
    'LOCATION': 'http://192.168.1.100:8080/content.xml'
});

// Withdraw a specific service
advertiser.withdraw('urn:schemas-upnp-org:service:ContentDirectory:1');

// Trigger an immediate notification for all services
advertiser.announceNow();

// Clean up when done (sends ssdp:byebye for all services)
advertiser.destroy();

Using the Authentication Provider

Control which hosts can discover your services:

import { Advertiser } from '@gibme/ssdp';

const allowedSubnets = ['192.168.1.', '10.0.0.'];

const advertiser = await Advertiser.create({
    interval: 10_000,
    services: {
        'my:custom:service': {}
    },
    authenticationProvider: (ipAddress) => {
        return allowedSubnets.some(subnet => ipAddress.startsWith(subnet));
    }
});

Low-Level SSDP Socket

For direct control over SSDP messaging:

import { SSDP } from '@gibme/ssdp';

const socket = await SSDP.create({ loopback: true, ttl: 2 });

socket.on('search', (payload, local, remote) => {
    console.log('Search from:', remote.address, 'for:', payload.getHeader('ST'));
});

socket.on('notification', (payload, local, remote) => {
    console.log('Notification:', payload.getHeader('NT'), payload.getHeader('NTS'));
});

socket.on('reply', (payload, local, remote) => {
    console.log('Reply:', payload.getHeader('ST'));
});

// Send a search
await socket.search('ssdp:all');

// Send a notification
await socket.notify('my:service:type', { USN: 'uuid:my-device::my:service:type' });

// Send a byebye
await socket.bye('my:service:type', { USN: 'uuid:my-device::my:service:type' });

socket.destroy();

Configuration Options

Common Options

| Option | Type | Default | Description | |---|---|---|---| | host | string | auto | Network interface to bind to | | loopback | boolean | false | Whether to receive messages sent by this instance | | ttl | number | 2 | Multicast TTL (time-to-live) |

Browser Options

| Option | Type | Default | Description | |---|---|---|---| | interval | number | 60000 | How often (ms) to search the network | | services | string \| string[] | — | Service types to subscribe to |

Advertiser Options

| Option | Type | Default | Description | |---|---|---|---| | interval | number | 60000 | How often (ms) to send notifications | | uuid | string | auto (v7) | UUID for this device instance | | services | Record<string, HeadersInit> | — | Services to advertise with their headers | | authenticationProvider | (ip: string) => boolean \| Promise<boolean> | () => true | Controls which hosts receive responses |

License

MIT