# How Cherry Studio's Local Transfer Service Discovers Devices on the Network

> Learn how Cherry Studio's local transfer service discovers network devices using mDNS and bonjour-service for automatic peer detection without manual IP setup.

- Repository: [CherryHQ/cherry-studio](https://github.com/cherryhq/cherry-studio)
- Tags: how-to-guide
- Published: 2026-02-27

---

**Cherry Studio uses multicast DNS (mDNS) via the `bonjour-service` library to automatically discover peers on the same LAN without manual IP configuration.**

The local transfer feature in [cherryhq/cherry-studio](https://github.com/cherryhq/cherry-studio) enables seamless file and message sharing between instances on the same network. At the heart of this capability lies a **multicast DNS (mDNS)** discovery mechanism that leverages the Bonjour protocol to locate available peers dynamically.

## How Device Discovery Works

When a user initiates a LAN transfer scan, the `LocalTransferService` in the main Electron process orchestrates the discovery workflow. The service implements a **zero-configuration networking** approach, meaning devices automatically find each other without requiring static IP addresses or manual configuration.

### Initializing the mDNS Client

The service maintains a singleton Bonjour instance through the `getBonjour()` method. This ensures efficient resource management by reusing the same mDNS client across multiple discovery sessions.

```typescript
private getBonjour(): Bonjour {
  if (!this.bonjour) {
    this.bonjour = new Bonjour()            // ← creates the mDNS client
  }
  return this.bonjour
}

```

*Source: [src/main/services/LocalTransferService.ts](https://github.com/cherryhq/cherry-studio/blob/main/src/main/services/LocalTransferService.ts#L95-L99)*

### Browsing for Cherry Studio Services

Once initialized, the service creates a Bonjour browser specifically looking for services of type **`cherrystudio`** over the **TCP** protocol. This filtered search ensures the application only detects relevant peers running Cherry Studio, ignoring other mDNS advertisements on the network.

```typescript
const browser = this.getBonjour().find({ type: SERVICE_TYPE, protocol: SERVICE_PROTOCOL })
this.browser = browser
this.bindBrowserEvents(browser)
browser.start()

```

The constants `SERVICE_TYPE = 'cherrystudio'` and `SERVICE_PROTOCOL = 'tcp'` are defined at the top of the service file, making the discovery criteria explicit and maintainable.

*Source: [src/main/services/LocalTransferService.ts](https://github.com/cherryhq/cherry-studio/blob/main/src/main/services/LocalTransferService.ts#L24-L26) & [L124-L130](https://github.com/cherryhq/cherry-studio/blob/main/src/main/services/LocalTransferService.ts#L124-L130)*

### Handling Peer Events

The `bindBrowserEvents()` method attaches three critical event listeners to the browser instance:

- **`up`** – Triggered when a new peer announces itself via mDNS. The service constructs a normalized `LocalTransferPeer` object containing the peer's name, host addresses, and port, then stores it in an internal map.
- **`down`** – Fired when a peer disappears from the network (e.g., application closed or network disconnected). The service removes the peer from the active map.
- **`error`** – Captures any discovery errors, logging them for debugging and surfacing issues through the service state.

*Source: [src/main/services/LocalTransferService.ts](https://github.com/cherryhq/cherry-studio/blob/main/src/main/services/LocalTransferService.ts#L138-L162)*

After processing these events, the service broadcasts the updated peer list to the renderer process via the `LocalTransfer_ServicesUpdated` IPC channel, ensuring the UI always reflects the current network topology.

## Implementing LAN Discovery in Your Application

Developers integrating with Cherry Studio's local transfer capabilities can leverage the exposed APIs to initiate scans and handle discovered devices.

### Starting a Network Scan

From the renderer process, trigger a discovery scan using the exposed API:

```typescript
// In a React component or UI handler
await window.api.localTransfer.startScan()

```

This invokes the `LocalTransfer_StartScan` IPC channel, which delegates to `LocalTransferService.startDiscovery()` in the main process.

### Listening for Discovered Devices

Subscribe to discovery updates to receive real-time peer information:

```typescript
const unsubscribe = window.api.localTransfer.onServicesUpdated(state => {
  console.log('Discovered LAN peers:', state.services)
})

// When the component unmounts
unsubscribe()

```

The callback receives a `LocalTransferState` object containing an array of `LocalTransferPeer` objects with details including host addresses, ports, and display names.

### Connecting to a Peer

Once discovered, initiate a connection to a specific peer:

```typescript
const peer = discoveredPeers[0]   // select target peer
const ack = await window.api.localTransfer.connect({
  host: peer.host,
  port: peer.port,
  token: 'your-auth-token'      // optional authentication
})
console.log('Handshake ACK:', ack)

```

This triggers the `LocalTransfer_Connect` IPC channel, handled by the `LanTransferClientService` in the main process.

### Stopping the Discovery Process

To conserve resources and network bandwidth, stop the scan when no longer needed:

```typescript
await window.api.localTransfer.stopScan()

```

This halts the Bonjour browser and clears the scanning state flag.

## Key Source Files and Architecture

Understanding the complete discovery flow requires familiarity with these specific files in the Cherry Studio repository:

| Component | File Path | Purpose |
|-----------|-----------|---------|
| **Core Service** | [`src/main/services/LocalTransferService.ts`](https://github.com/cherryhq/cherry-studio/blob/main/src/main/services/LocalTransferService.ts) | Implements mDNS discovery, Bonjour instance management, peer state tracking, and IPC broadcasting |
| **Preload Bridge** | [`src/preload/index.ts`](https://github.com/cherryhq/cherry-studio/blob/main/src/preload/index.ts) | Exposes `localTransfer` API methods (`startScan`, `stopScan`, `onServicesUpdated`) to the renderer process |
| **UI Integration** | [`src/renderer/src/components/Popups/LanTransferPopup/hook.ts`](https://github.com/cherryhq/cherry-studio/blob/main/src/renderer/src/components/Popups/LanTransferPopup/hook.ts) | Demonstrates React hook patterns for consuming LAN discovery APIs in the UI layer |
| **Type Definitions** | [`packages/shared/config/types.ts`](https://github.com/cherryhq/cherry-studio/blob/main/packages/shared/config/types.ts) | Defines `LocalTransferPeer`, `LocalTransferState`, and related TypeScript interfaces |
| **IPC Channels** | [`src/shared/IpcChannel.ts`](https://github.com/cherryhq/cherry-studio/blob/main/src/shared/IpcChannel.ts) | Enumerates `LocalTransfer_StartScan`, `LocalTransfer_ServicesUpdated`, and other channel constants |

These files collectively demonstrate the full stack implementation of zero-configuration networking, from the low-level mDNS browsing in the main process to the high-level React hooks consumed by the user interface.

## Summary

Cherry Studio's local transfer service implements **zero-configuration device discovery** through the following key mechanisms:

- **mDNS/Bonjour Protocol**: Uses the `bonjour-service` library to handle multicast DNS advertisements without requiring central DNS servers or manual IP configuration.
- **Service Type Filtering**: Specifically searches for `_cherrystudio._tcp` services, ensuring only relevant peers are discovered.
- **Event-Driven Architecture**: Implements `up`, `down`, and `error` event handlers to maintain real-time awareness of network topology changes.
- **IPC Integration**: Broadcasts discovery results to the renderer process via `LocalTransfer_ServicesUpdated`, enabling reactive UI updates.
- **Resource Management**: Maintains a singleton Bonjour instance and provides explicit `stopScan` functionality to prevent resource leaks.

## Frequently Asked Questions

### How does Cherry Studio find other devices without knowing their IP addresses?

Cherry Studio uses **multicast DNS (mDNS)**, a zero-configuration networking protocol that allows devices to broadcast their presence on the local network using hostnames rather than static IP addresses. When a scan starts, the application listens for mDNS advertisements on the `_cherrystudio._tcp` service type, automatically extracting IP addresses and port numbers from the broadcast packets.

### What happens when a device goes offline during a LAN transfer session?

The `LocalTransferService` binds a `down` event listener to the Bonjour browser instance. When a peer stops advertising its mDNS service—either because the application closed or the network disconnected—the browser fires the `down` event. The service then removes the peer from its internal map and broadcasts the updated state via IPC, causing the UI to immediately reflect the disconnection.

### Can Cherry Studio discover devices across different subnets or VLANs?

Standard mDNS operates on multicast address `224.0.0.251` with TTL (Time To Live) typically set to 255, meaning packets usually do not traverse routers or cross subnet boundaries. Therefore, Cherry Studio's local transfer service generally only discovers peers on the **same local network segment**. Cross-subnet discovery would require mDNS reflectors or specific network infrastructure configuration outside the application's control.

### Is the device discovery process secure against unauthorized network scanning?

The discovery mechanism itself relies on open mDNS broadcasts, meaning any device on the network can theoretically see that a Cherry Studio instance is running. However, the actual **connection and data transfer** require an explicit `connect` call that can include authentication tokens. As shown in the `LocalTransferService` implementation, while discovery is passive and broadcast-based, the subsequent TCP connection establishment can enforce authorization checks before exchanging sensitive data.