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

@entree_pos/beacon

v1.0.1

Published

Zero-dependency UDP service discovery for Node.js applications on a local network.

Readme

@entree_pos/beacon

Find a Node.js service on the same local network without asking users to enter an IP address.

@entree_pos/beacon is a zero-dependency UDP discovery library for Node.js 18+. A server listens for a short service name. A client broadcasts that name and receives the server address and port.

npm install @entree_pos/beacon

See the visual guide for the protocol flow, copy-ready examples, and option reference.

Quick start

Start a service beacon:

const beacon = require("@entree_pos/beacon");

const info = { address: "192.168.1.20", port: 8888 };
const listener = beacon.create("Entree POS").listen(15666, true, info);

await listener.ready;
console.log("Ready for discovery");

Discover it from another machine on the LAN:

import beacon from "@entree_pos/beacon";

const service = await beacon.create("Entree POS").connect(15666);

console.log(service);
// { address: "192.168.1.20", port: 8888 }

Both sides must use the same beacon name and discovery port. UDP broadcast must also be allowed by the client network and host firewall.

Use the sender address

When the application service uses port 8888, the listener can omit info:

const listener = beacon.create("Entree POS").listen(15666);

The listener replies with HELLO Entree POS. The client uses the UDP sender's address and port 8888 by default:

const service = await beacon.create("Entree POS").connect({
  defaultServicePort: 8888
});

This is useful when a machine has several network interfaces and the address seen by the client is more reliable than a configured address.

Resolve service information per client

Pass a function when the advertised address depends on the requesting client:

const listener = beacon.create("Kitchen API").listen({
  info(client) {
    return {
      address: addressFor(client.address),
      port: 9100
    };
  }
});

Cancel discovery

Discovery retries until the timeout is reached. Use an AbortSignal when a screen closes or the application is shutting down:

const controller = new AbortController();

const pending = beacon.create("Entree POS").connect({
  timeout: 15000,
  retryInterval: 3000,
  signal: controller.signal
});

controller.abort();
await pending;

A timeout rejects with BeaconTimeoutError and code BEACON_TIMEOUT.

Close the listener

listen() returns an independent listener. Close it during application shutdown so Node.js can exit cleanly:

await listener.close();

The listener emits listening, query, response, error, and close events. It also exposes a ready promise and an address() method.

Port or options object

Use a port for the shortest form:

await beacon.create("Entree POS").connect(15666);

Use an object when discovery needs additional controls:

await beacon.create("Entree POS").connect({
  port: 15666,
  timeout: 10000,
  retryInterval: 2000,
  signal: controller.signal
});

The callback form also works:

beacon.create("Entree POS").connect(15666, (service) => {
  console.log(service.address, service.port);
});

The original create().listen() and create().connect() design is the primary API. Unlike the internal module, create() now returns an independent instance. Multiple names and simultaneous discovery requests do not share one mutable global socket.

Android compatibility

By default, every matching request also sends ANDROID <name> to the client's discovery port. This preserves the Entree POS Android discovery behavior. Disable it for other protocols:

beacon.create("My API").listen({
  androidEcho: false
});

Defaults

| Setting | Default | | --- | --- | | Beacon name | BEACON TOWER | | Discovery port | 15666 | | Legacy service port | 8888 | | Retry interval | 3000ms | | Discovery timeout | 15000ms | | Broadcast address | 255.255.255.255 | | Android echo | Enabled |

Use timeout: 0 only when another part of the application owns cancellation.

Documentation

Requirements

  • Node.js 18 or newer
  • IPv4 UDP broadcast on the local network
  • No runtime dependencies

License

MIT