Capacitor plugin for Zeroconf (mDNS) service discovery and broadcasting.
npm install @laravelka/zeroconf
npx cap sync
- Xcode 15.0+
- CocoaPods
- Open your project in Xcode:
npx cap open ios
- Add the following keys to your
Info.plist
file:
<!-- Local Network Usage Description -->
<key>NSLocalNetworkUsageDescription</key>
<string>This app needs access to find and connect to local network devices</string>
<!-- Bonjour Services -->
<key>NSBonjourServices</key>
<array>
<string>_http._tcp.</string>
<!-- Add other service types your app will use -->
</array>
- Android Studio Electric Eel (2022.1.1) or newer
- Android SDK and Platform Tools installed
- Java 17 or newer
- Open your project in Android Studio:
npx cap open android
- Add the following permissions to your
android/app/src/main/AndroidManifest.xml
:
<!-- Required permissions -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
- Update your
android/variables.gradle
to ensure compatibility:
ext {
minSdkVersion = 26
compileSdkVersion = 34
targetSdkVersion = 34
androidxActivityVersion = '1.7.0'
}
- Make sure your
android/build.gradle
has the correct Java version:
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
}
import { ZeroConf } from '@laravelka/zeroconf';
import type { PluginListenerHandle, ZeroConfWatchResult } from '@laravelka/zeroconf';
let listener: PluginListenerHandle;
// Listen for service discovery events
const setupListeners = async () => {
listener = await ZeroConf.addListener('discover', (result: ZeroConfWatchResult) => {
console.log('Service discovered:', result);
// result.action will be 'added', 'removed', or 'resolved'
// result.service contains service information
});
};
// Register a service
await ZeroConf.register({
type: '_http._tcp.',
domain: 'local.',
name: 'MyService',
port: 3000,
txtRecord: {
path: '/api'
}
});
// Start watching for services
await ZeroConf.watch({
type: '_http._tcp.',
domain: 'local.'
});
// Cleanup listeners when done
await listener?.remove();
// Later: stop watching and cleanup
await ZeroConf.unwatch({
type: '_http._tcp.',
domain: 'local.'
});
await ZeroConf.unregister({
type: '_http._tcp.',
domain: 'local.',
name: 'MyService'
});
// Stop all discoveries and unregister all services
await ZeroConf.stop();
// Clean up resources when done
await ZeroConf.close();
Add the following to your capacitor.config.ts
:
/// <reference types="@laravelka/zeroconf" />
import { CapacitorConfig } from '@capacitor/cli';
const config: CapacitorConfig = {
plugins: {
ZeroConf: {
// Optional configuration options can be added here
}
}
};
export default config;
addListener('discover', ...)
getHostname()
register(...)
unregister(...)
watch(...)
unwatch(...)
stop()
close()
- Interfaces
Main ZeroConf plugin interface.
addListener(eventName: 'discover', listenerFunc: (result: ZeroConfWatchResult) => void) => Promise<PluginListenerHandle>
Add a listener for service discovery events.
Param | Type | Description |
---|---|---|
eventName |
'discover' |
- The name of the event to listen for |
listenerFunc |
(result: ZeroConfWatchResult) => void |
- Callback function that will be called when a service is discovered |
Returns: Promise<PluginListenerHandle>
Since: 1.0.0
getHostname() => Promise<{ hostname: string; }>
Get the hostname of the device.
Returns: Promise<{ hostname: string; }>
Since: 1.0.0
register(options: { type: string; domain?: string | undefined; name: string; port: number; txtRecord?: { [key: string]: string; } | undefined; }) => Promise<void>
Register a new service.
Param | Type | Description |
---|---|---|
options |
{ type: string; domain?: string; name: string; port: number; txtRecord?: { [key: string]: string; }; } |
- Service registration options |
Since: 1.0.0
unregister(options: { type: string; name: string; }) => Promise<void>
Unregister a previously registered service.
Param | Type | Description |
---|---|---|
options |
{ type: string; name: string; } |
- Service unregistration options |
Since: 1.0.0
watch(options: { type: string; domain?: string; }) => Promise<void>
Start watching for services of a specific type.
Param | Type | Description |
---|---|---|
options |
{ type: string; domain?: string; } |
- Service watch options |
Since: 1.0.0
unwatch(options: { type: string; }) => Promise<void>
Stop watching for services of a specific type.
Param | Type | Description |
---|---|---|
options |
{ type: string; } |
- Service unwatch options |
Since: 1.0.0
stop() => Promise<void>
Stop all ongoing service discoveries and unregister all services.
Since: 1.0.0
close() => Promise<void>
Close the Zeroconf instance and clean up resources.
Since: 1.0.0
Prop | Type |
---|---|
remove |
() => Promise<void> |
Result of a ZeroConf service discovery event.
Prop | Type |
---|---|
action |
'added' | 'removed' | 'resolved' |
service |
ZeroConfService |
Represents a discovered ZeroConf service.
Prop | Type |
---|---|
domain |
string |
type |
string |
name |
string |
port |
number |
hostname |
string |
ipv4Addresses |
string[] |
ipv6Addresses |
string[] |
txtRecord |
{ [key: string]: string; } |
import { ZeroConf } from '@laravelka/zeroconf';
import type { PluginListenerHandle, ZeroConfWatchResult } from '@laravelka/zeroconf';
class ZeroConfExample {
private listener: PluginListenerHandle | null = null;
async initialize() {
// Setup event listener
this.listener = await ZeroConf.addListener('discover', (result: ZeroConfWatchResult) => {
console.log('Service discovered:', result);
// result.action will be 'added', 'removed', or 'resolved'
// result.service contains service information
});
// Register our service
await ZeroConf.register({
type: '_http._tcp.',
domain: 'local.',
name: 'MyService',
port: 3000,
txtRecord: {
path: '/api'
}
});
// Start watching for services
await ZeroConf.watch({
type: '_http._tcp.',
domain: 'local.'
});
}
async cleanup() {
// Remove event listener
if (this.listener) {
await this.listener.remove();
this.listener = null;
}
// Stop watching for services
await ZeroConf.unwatch({
type: '_http._tcp.',
domain: 'local.'
});
// Unregister our service
await ZeroConf.unregister({
type: '_http._tcp.',
domain: 'local.',
name: 'MyService'
});
// Stop all discoveries and unregister all services
await ZeroConf.stop();
// Clean up resources
await ZeroConf.close();
}
}
- ✅ Android (using JmDNS)
- ✅ iOS (using Network.framework and NetService)
- Capacitor 7.0.0 or newer
- iOS 13.0 or newer (Xcode 15.0+)
- Android API 26 (Android 8.0) or newer
MIT