{"id":10581,"library":"bonjour","title":"bonjour: Zeroconf/mDNS Service Discovery","description":"The `bonjour` package provides a pure JavaScript implementation of the Bonjour (also known as Zeroconf or mDNS/DNS-SD) protocol for Node.js environments. It allows applications to publish services on the local network, making them discoverable by other Bonjour-compatible devices, and to discover services advertised by others. The library is currently at version 3.5.1 and has an infrequent, as-needed release cadence. Its key differentiator is its full implementation in JavaScript, relying on the `multicast-dns` package for the underlying DNS operations. Unlike some alternatives, it offers both service advertisement and discovery capabilities within a single, lightweight API, making it suitable for local network peer-to-peer communication without central servers.","status":"active","version":"3.5.1","language":"javascript","source_language":"en","source_url":"https://github.com/watson/bonjour","tags":["javascript","bonjour","zeroconf","zero","configuration","mdns","dns","service","discovery"],"install":[{"cmd":"npm install bonjour","lang":"bash","label":"npm"},{"cmd":"yarn add bonjour","lang":"bash","label":"yarn"},{"cmd":"pnpm add bonjour","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core dependency for multicast DNS communication.","package":"multicast-dns","optional":false},{"reason":"Used for parsing and formatting DNS TXT records.","package":"dns-txt","optional":false}],"imports":[{"note":"The default export is a factory function that needs to be called to get the Bonjour instance. TypeScript users may need `import bonjourFactory = require('bonjour');` or configure `esModuleInterop`.","wrong":"import { bonjour } from 'bonjour'; // Incorrect named import\nconst bonjour = new bonjour();    // Not a class","symbol":"bonjourFactory","correct":"import bonjourFactory from 'bonjour';\nconst bonjour = bonjourFactory();"},{"note":"In CommonJS, `require('bonjour')` returns a factory function that must be immediately invoked to get the Bonjour instance with its methods (`publish`, `find`, etc.).","wrong":"const bonjour = require('bonjour'); // Missing function call\nconst { publish } = require('bonjour'); // No named exports for methods","symbol":"bonjourInstance","correct":"const bonjour = require('bonjour')();"},{"note":"Service objects are returned by `bonjour.publish()` and `browser.on('up', ...)` events. They are not directly importable classes.","wrong":"import { Service } from 'bonjour'; // Not directly exported","symbol":"Service","correct":"const service = bonjour.publish(...);"}],"quickstart":{"code":"import bonjourFactory from 'bonjour';\n\nconst bonjour = bonjourFactory();\n\n// Advertise an HTTP server on port 3000\nconst service = bonjour.publish({\n  name: 'My Bonjour Web Server',\n  type: 'http',\n  port: 3000,\n  txt: { version: '1.0', path: '/' }\n});\n\nservice.on('up', () => {\n  console.log('Service published:', service.name, service.host, service.port);\n});\n\n// Browse for all http services\nconst browser = bonjour.find({ type: 'http' });\n\nbrowser.on('up', (foundService) => {\n  console.log('Found an HTTP server:', foundService.name, foundService.host, foundService.port);\n});\n\n// Stop browsing after 10 seconds and destroy all services/connections\nsetTimeout(() => {\n  console.log('Stopping discovery and unpublishing service...');\n  browser.stop();\n  bonjour.unpublishAll(() => {\n    console.log('All services unpublished.');\n    bonjour.destroy(); // Close the UDP socket\n    console.log('Bonjour instance destroyed.');\n  });\n}, 10000);\n\n// Handle process exit to ensure cleanup\nprocess.on('SIGINT', () => {\n  console.log('Received SIGINT. Destroying Bonjour instance...');\n  bonjour.destroy();\n  process.exit();\n});","lang":"javascript","description":"This quickstart demonstrates how to initialize `bonjour`, publish an HTTP service, and then discover existing HTTP services on the local network, with proper cleanup."},"warnings":[{"fix":"Always ensure `bonjour.destroy()` is called on application shutdown, for instance, by listening to `process.on('exit')` or `process.on('SIGINT')`.","message":"The `bonjour` factory function (`require('bonjour')()` or `bonjourFactory()`) creates an instance. It is crucial to call `bonjour.destroy()` when the application exits or the Bonjour functionality is no longer needed, to properly close the underlying UDP socket and stop broadcasting, preventing resource leaks.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Verify network settings, ensure UDP ports are open (typically 5353 for mDNS), and test within the same local subnet. Avoid using VPNs during development if Bonjour discovery is critical.","message":"Bonjour relies on UDP multicast, which can be affected by network configurations, firewalls, and VPNs. Services might not be discoverable across different subnets or through restrictive network policies.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Implement robust handling for service presence, assuming services might appear or disappear with some delay. Consider a debounce or timeout mechanism for reacting to service discovery events.","message":"Service advertisements might not be immediately visible, and discovery can take a few seconds as it relies on multicast DNS broadcasts. Conversely, 'down' events for services are not always instantaneous, as a device might disappear without sending a 'goodbye' message.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"For new projects, consider `npm install bonjour-service` and consult its documentation for usage. For existing projects, be aware that `bonjour` may not receive significant new features or compliance updates.","message":"While `bonjour` is still active, an official rewrite in TypeScript named `bonjour-service` is available. For new projects, especially those using TypeScript, `bonjour-service` might be a more modern and actively developed alternative with better RFC compliance.","severity":"deprecated","affected_versions":">=3.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure no other Bonjour/mDNS service (or another instance of your application) is running. On some systems, restarting the machine can resolve this. You can also pass custom `port` options to the `multicast-dns` server when initializing `bonjour` if necessary, though this might hinder interoperability.","cause":"Another process on the system is already using UDP port 5353, which is the standard mDNS port `bonjour` attempts to bind to.","error":"Error: bind EADDRINUSE 0.0.0.0:5353"},{"fix":"Double-check that both the publishing and browsing applications are on the same local network segment and are using identical service `type` strings. Temporarily disable firewalls for testing. Use network debugging tools (like Wireshark) to inspect mDNS traffic on port 5353.","cause":"This typically indicates a network issue (firewall, router blocking multicast, client/server on different subnets) or an incorrect service `type` being searched for versus what is being published.","error":"Service not found or 'up' event never fires."},{"fix":"Use `const bonjour = require('bonjour')();` for CommonJS or `import bonjourFactory from 'bonjour'; const bonjour = bonjourFactory();` for ESM to correctly initialize the Bonjour instance.","cause":"This error occurs when `require('bonjour')` or `import bonjour from 'bonjour'` is not immediately invoked as a function to create the instance.","error":"TypeError: bonjour is not a function"}],"ecosystem":"npm"}