π Major Update v3.4.0+: This package has been re-architected to be Zero-Dependency. It now uses native Node.js modules (
dgram,crypto) for maximum performance, security, and compatibility. No more heavy dependencies likebonjour-serviceormulticast-dns.
mDNS Listener Advanced is a robust, cross-platform Node.js library for Multicast DNS (mDNS) operations. It allows you to:
- Listen for specific
.localhostnames. - Publish your own device/service to the network.
- Scan/Discover all devices and services on the network (Service Discovery).
Compatible with mdns, Avahi, Bonjour, and Zeroconf.
- Node.js: v22 or later (Recommended).
- OS: Fully tested on Windows 11, Ubuntu 20.04+, and macOS (Sonoma/Sequoia/Tahoe).
- Not tested on Docker containers.
- This library need to access the local network to work properly.
npm install mdns-listener-advanced
# or preferred way
yarn add mdns-listener-advanced- π¦ Zero Dependencies: Lightweight and secure.
- π Targeted Listening: Detect specific devices by name (e.g., MyDevice.local).
- π‘ Service Discovery: Scan the network for all services (e.g., Google Cast, Printers).
- π’ Native Publisher: Announce your presence without external tools.
- π‘οΈ TypeScript: Written in TypeScript with full type definitions included.
Listen for specific devices defined in your constructor or hosts file.
import Core, { EmittedEvent } from "mdns-listener-advanced";
// Look for a device named "MyDevice2"
const mdns = new Core(["MyDevice2"], null, {
debug: false
});
const event = mdns.listen();
// 1. Handle targeted response
event.on(EmittedEvent.RESPONSE, (found_hostnames) => {
console.log("β
Found Target:", found_hostnames);
// mdns.stop(); // Stop listening if needed
});
// 2. Handle errors
event.on(EmittedEvent.ERROR, (error) => {
console.error("β Error:", error);
});New in v3.4.0: actively query the network to find devices (Printers, Chromecast, HomeKit, etc.).
import { Core, EmittedEvent, Device } from 'mdns-listener-advanced';
// or import Core,{ EmittedEvent, Device } from 'mdns-listener-advanced';
const mdns = new Core();
const event = mdns.listen();
event.on(EmittedEvent.DISCOVERY, (device: Device) => {
console.log(`π Discovered [${device.type}]:`, device.name, device.data);
});
// Scan for Google Cast devices
mdns.scan("_googlecast._tcp.local");
// OR Scan for EVERYTHING
// mdns.scan("_services._dns-sd._udp.local");Announce your service to the network.
import { Core } from "mdns-listener-advanced";
// or import Core,{ EmittedEvent, Device } from 'mdns-listener-advanced';
const mdns = new Core();
// Publish "MyCoolService.local"
const customData = { hello: "world" };
mdns.publish("MyCoolService",customData, 30000); // 30000 ms = 30 seconds by default
// Your device is now visible to other mDNS scanners!
// // 2. Start Listener
const event = mdns.listen();
// // --- HANDLERS ---
event.on(EmittedEvent.RESPONSE, (found_hostnames: Device[]) => {
mdns.info("β
Found TARGETED Host:", found_hostnames);
});
// stopoutput:
[MDNS ADVANCED] INFO: β
Found TARGETED Host: [
{
name: 'MyDevice2',
type: 'TXT',
data: {
uuid: '"eec91263-de12-4525-ba08-81adad17-ceb3"',
ipv4: '"192.168.1.102"',
hello: 'world'
}
}
]Clone the repository and run the following command:
# optional install (no dependencies required to run the example)
# yarn install
yarn startClass: Core
// All args are optional
new Core(hostsList, mdnsHostsPath, options, logger)| Parameter | Type | Description |
|---|---|---|
| hostsList | string[] | Optional array of hostnames to listen for (e.g. ['device1']). |
| mdnsHostsPath | string | Optional absolute path to a custom hosts file. |
| options | Options | "Config object: { debug: boolean, disableListener: boolean, disablePublisher: boolean }." |
| logger | any | "Custom logger instance (must have .info, .debug, .warn, .error)." |
| Method | Description |
|---|---|
| listen(ref) | Starts the UDP socket and joins the Multicast group. Returns the EventEmitter, you can provide a string to listen for a specific host check example.ts. |
| publish(name,data, interval) | "Broadcasts an mDNS response, announcing name.local with your IP address. add data to the TXT record, personalize the interval by default set to 30000ms." |
| scan(serviceType) | (New) Sends a query to the network. Default serviceType is _services._dns-sd._udp.local. |
| stop() | Closes the socket and removes all event listeners. |
| Event Name | Enum | Payload Type | Description |
|---|---|---|---|
| """response""" | EmittedEvent.RESPONSE | Device[] | Fired when a Targeted Host (from your list) is found. |
| """discovery""" | EmittedEvent.DISCOVERY | Device | "Fired when scan() finds ANY device (PTR, SRV, or A records)." |
| """raw_response""" | EmittedEvent.RAW_RESPONSE | object | The full raw packet structure (advanced debugging). |
| """error""" | EmittedEvent.ERROR | Error | Fired on socket errors or configuration issues. |
You can optionally use a file to manage the list of devices you want to detect (Targeted Listening).
Location:
- Windows:
C:\Users\<username>\.mdns-hosts - Linux/macOS:
~/.mdns-hosts
LivingRoomTV
OfficePrinter
RaspberryPi
If you do not provide a constructor list or this file, the listener will warn you but still function (useful if you only want to use scan() or publish())
- Firewall: mDNS uses UDP port 5353. Ensure your firewall allows traffic on this port.
- Docker: If running in Docker, you must use network_mode: "host" so the container can receive Multicast packets from the physical network.
- Windows: You might need to allow Node.js through the Windows Defender Firewall on the first run.
- macOS + Docker limitations : running docker in host mode might not work on macOS, since the container is not able to access the host network.
Issues: Open an issue here Contact: Connect on LinkedIn
I dedicate time and effort on writing and maintaining this library since 2017 and I'm grateful for your support.
If this library saved you time, consider Donating!
Original Credit: Based on concepts from @Richie765, now fully rewritten for modern Node.js and TypeScript.