# Tauri Desktop App IPC Bridge to Rust Sidecar: How OpenHuman Connects UI to Core

> Discover OpenHuman's Tauri IPC bridge architecture. Learn how React UI communicates with a Rust sidecar, isolating business logic and managing sidecar lifecycle automatically.

- Repository: [Tiny Humans/openhuman](https://github.com/tinyhumansai/openhuman)
- Tags: architecture
- Published: 2026-05-12

---

**The OpenHuman desktop application uses a Tauri IPC bridge to relay JSON-RPC calls from the React frontend to a standalone Rust sidecar binary, managing the sidecar lifecycle automatically while keeping business logic isolated from the UI.**

OpenHuman’s architecture separates the lightweight desktop interface from heavy computational workloads. The frontend runs inside a Tauri-hosted WebView, while the `openhuman-core` Rust sidecar handles persistence, QuickJS skill execution, and blockchain operations. This guide examines the IPC bridge implementation that synchronizes these components according to the `tinyhumansai/openhuman` source code.

## The Two-Layer IPC Architecture

The bridge operates through two distinct layers. First, the **Tauri IPC command** (`core_rpc_relay`) receives requests from the frontend via the standard Tauri `invoke` mechanism. Second, an **HTTP JSON-RPC client** forwards these requests to the sidecar's local API endpoint at `http://127.0.0.1:<core_port>/rpc`.

This design keeps the WebView sandboxed while allowing access to native system capabilities. All network traffic remains internal to localhost, eliminating CORS concerns and external exposure.

## The IPC Relay Command

The entry point resides in [`app/src-tauri/src/commands/core_relay.rs`](https://github.com/tinyhumansai/openhuman/blob/main/app/src-tauri/src/commands/core_relay.rs). When the frontend calls `invoke('core_rpc_relay', …)`, Tauri deserializes the payload into a `CoreRpcRequest` struct containing three critical fields:

- **method**: The JSON-RPC method name (e.g., `agent.run`, `wallet.prepare_transfer`)
- **params**: An optional map of parameters for the method
- **serviceManaged**: A boolean flag indicating whether Tauri should auto-start the core process

The handler first ensures the sidecar is alive by delegating to the core process manager. Once confirmed, it forwards the request to the HTTP client layer.

## Sidecar Lifecycle Management

Before any RPC call reaches the business logic, the system guarantees the sidecar is running. The [`app/src-tauri/src/core_process.rs`](https://github.com/tinyhumansai/openhuman/blob/main/app/src-tauri/src/core_process.rs) module handles this responsibility, implementing logic to either spawn a new `openhuman-core` binary or reuse an existing child process.

This manager tracks the sidecar's health and port allocation, ensuring the HTTP client always has a valid target endpoint. If `serviceManaged` is true and the process is not running, the manager initiates startup automatically before the relay proceeds.

## HTTP Client Implementation

The actual communication with the sidecar happens in [`app/src-tauri/src/core_rpc.rs`](https://github.com/tinyhumansai/openhuman/blob/main/app/src-tauri/src/core_rpc.rs). This client constructs a standards-compliant JSON-RPC envelope:

```json
{
  "jsonrpc": "2.0",
  "method": "agent.get_profile",
  "params": {},
  "id": 1
}

```

The client injects authentication by reading the bearer token from `~/.openhuman-staging/core.token` and adding it to the HTTP headers. It then POSTs the envelope to the sidecar's RPC endpoint and returns the response (or error) back through the Tauri command chain to the frontend.

## Frontend TypeScript Integration

The React codebase interacts with this bridge through a thin wrapper defined in [`app/src/utils/coreRpcClient.ts`](https://github.com/tinyhumansai/openhuman/blob/main/app/src/utils/coreRpcClient.ts). This utility abstracts the Tauri invoke mechanism:

```typescript
import { invoke } from '@tauri-apps/api/tauri';

export async function coreRpc<T>(method: string, params?: Record<string, any>) {
  const { result } = await invoke('core_rpc_relay', {
    request: { method, params },
  });
  return result as T;
}

// Usage example
const profile = await coreRpc<UserProfile>('agent.get_profile');

```

All high-level UI operations—wallet transfers, agent execution, memory queries—flow through this helper, maintaining type safety while accessing native Rust capabilities.

## Core-Side Request Dispatching

On the receiving end, the sidecar implements a JSON-RPC dispatcher in [`src/rpc/dispatch.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/rpc/dispatch.rs) and [`src/rpc/mod.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/rpc/mod.rs). These modules parse incoming requests, route them to the appropriate domain controllers, and serialize responses back to the HTTP client.

This completes the round-trip: TypeScript invokes Tauri → Tauri manages process → HTTP client POSTs → Sidecar dispatches → Response propagates back through the chain.

## Summary

- OpenHuman uses a **hybrid IPC architecture** combining Tauri's native commands with HTTP JSON-RPC for sidecar communication
- The `core_rpc_relay` command in [`app/src-tauri/src/commands/core_relay.rs`](https://github.com/tinyhumansai/openhuman/blob/main/app/src-tauri/src/commands/core_relay.rs) serves as the sole bridge between frontend and business logic
- **Automatic lifecycle management** via [`app/src-tauri/src/core_process.rs`](https://github.com/tinyhumansai/openhuman/blob/main/app/src-tauri/src/core_process.rs) ensures the sidecar is running before dispatching requests
- Authentication uses a **bearer token** stored in `~/.openhuman-staging/core.token`, injected by the HTTP client in [`app/src-tauri/src/core_rpc.rs`](https://github.com/tinyhumansai/openhuman/blob/main/app/src-tauri/src/core_rpc.rs)
- Frontend code uses the `coreRpc` helper in [`app/src/utils/coreRpcClient.ts`](https://github.com/tinyhumansai/openhuman/blob/main/app/src/utils/coreRpcClient.ts) to maintain clean separation between UI and native operations

## Frequently Asked Questions

### What is the difference between Tauri commands and the sidecar process?

Tauri commands run inside the main Rust process that hosts the WebView, while the sidecar (`openhuman-core`) is a separate binary launched as a child process. Commands handle window management and OS integration, whereas the sidecar owns business logic like agent execution and wallet management. The IPC bridge connects these two Rust-based components.

### How does the application handle sidecar startup and crashes?

The [`core_process.rs`](https://github.com/tinyhumansai/openhuman/blob/main/core_process.rs) module implements a process manager that monitors the sidecar's lifecycle. When the frontend issues a request with `serviceManaged: true`, the manager checks if the process is running and spawns it if necessary. The manager tracks the process handle and port binding, automatically restarting if the sidecar becomes unresponsive.

### Is the communication between frontend and sidecar secure?

Yes. Although the HTTP traffic flows over localhost, the sidecar requires a bearer token for authentication. The token is stored in the user's home directory at `~/.openhuman-staging/core.token` and is injected into every request header by the Tauri-side HTTP client. External processes cannot access this token without system-level privileges.

### What happens if the sidecar port is already in use?

The core process manager in [`app/src-tauri/src/core_process.rs`](https://github.com/tinyhumansai/openhuman/blob/main/app/src-tauri/src/core_process.rs) handles port allocation dynamically. If the default port is unavailable, the manager either coordinates with an existing sidecar instance or allocates a new port, ensuring the HTTP client always targets the correct endpoint. The `core_rpc_relay` command waits for this handshake to complete before forwarding requests.