---
url: /intro/architecture.md
---
# How it works

camera.ui is **server-centric**: one server, running on your hardware, does all the work. It connects to your cameras, streams and records video, runs detection, and serves the interface. The browser and the mobile apps are **viewers** of that server. The desktop app can be a viewer too, or run the server itself.

## One self-contained server

The camera.ui server bundles everything it needs to run: the web interface, a built-in **streaming engine** (our own go2rtc build) for live video, and its own **video processing** for decoding and recording. Your settings, cameras, users, and events live in a small **local database** on the same machine.

Nothing leaves your network unless you turn on [remote access](/remote/). There is no external database, and no cloud account is required to run a server.

## The big picture

```mermaid
flowchart LR
  cam[Cameras<br/>RTSP · ONVIF]

  subgraph server[camera.ui server · your hardware]
    direction TB
    g[Streaming engine] --> fw[Frame worker<br/>one per camera]
    fw --> det[Detection<br/>motion → objects → faces · plates<br/>audio in parallel]
    det --> nvr[(NVR plugin<br/>recordings + push)]
    g --> api[Web UI + API]
    nvr --> api
  end

  cam --> g
  api --> viewers[Viewers<br/>web · desktop · mobile]
  api -. optional .-> remote[Remote access<br/>Cloud · tunnel]
  remote -. from anywhere .-> viewers
```

## From camera to notification

1. **Streaming.** The streaming engine connects to each camera and turns its feed into browser-friendly live video (WebRTC and MSE). Streams are kept "warm" so live view and snapshots load instantly.
2. **Per-camera analysis.** Every camera gets its own **frame worker**, a background process that decodes the video and runs detection. A problem with one camera does not affect the others.
3. **Layered detection.** Cheap motion detection runs first and only wakes the heavier AI on movement: object detection, then faces, license plates, classification, and semantic (CLIP) analysis. Audio is analyzed in parallel. This "cascade" keeps CPU and GPU use low.\[^detect]
4. **Events & recording.** When detection fires, the server builds an **event** with segments, thumbnails, and the objects, faces, or plates it found. The **NVR plugin** records the footage, stores it, and serves it back for playback.\[^license]
5. **Notifications.** Events can trigger push notifications and run [automations](/automations/).\[^license]

## Plugins make it extensible

Much of camera.ui is delivered by **plugins** from the in-app store. Each plugin runs in its own process, so a failing plugin can't take down the server, and it restarts automatically after a crash.

Plugins provide:

* **Camera sources.** ONVIF and other camera protocols.
* **Detectors.** Motion engines and the AI backends (CoreML, ONNX, OpenVINO, NCNN, Coral, Hailo).
* **Recording & notifications.** The NVR plugin records your footage and sends push notifications.
* **Smart-home bridges.** Apple HomeKit.

Learn more under [Plugins](/plugins/).

## Apps: desktop, mobile, web

Every app shows the same interface, but their roles differ:

* The **[desktop app](/install/desktop)** can be the **server itself** (all-in-one), a **viewer** that connects to another server, or a **worker** that helps another server with decoding, detection, or a plugin. You choose on first launch, and can switch anytime. See [Scaling across machines](#scaling-across-machines).
* The **[mobile apps](/install/mobile)** and the **browser** are always **viewers**.

How viewers reach the server:

* On your network, the browser and a desktop viewer connect **directly**.
* The **mobile apps** connect directly over your local network at home, and through **camera.ui Cloud** when you're away.\[^cloud-optional]
* A browser away from home uses whichever [remote access](/remote/) option you set up: camera.ui Cloud, a Cloudflare tunnel, or your own domain.

You can also save more than one server as an **Instance** and switch between them from the same app.

## Scaling across machines

Extra machines can join as **workers**. A worker takes over decoding and detection for some cameras, or runs an entire plugin (for a detector that needs hardware the main server lacks). Cameras and plugins assigned to a worker **fall back** to the main server while the worker is offline and move back once it reconnects. See [Workers](/admin/workers).

## Reaching it from outside

From outside your network you can use camera.ui Cloud, a Cloudflare tunnel, a custom domain or port-forwarding. All are optional. See [Remote access](/remote/).

\[^detect]: Detection needs a detection plugin that matches your hardware (CoreML, ONNX, OpenVINO, NCNN, or an edge accelerator like Coral or Hailo). See [Detection & AI](/detection/).
\[^license]: An active camera.ui subscription covers recording (NVR) and the features built on it, such as playback, export, face recognition, semantic search, and AI descriptions, plus push notifications. Live view and real-time detection are free.
\[^cloud-optional]: camera.ui Cloud is optional. On your own network everything stays local, and your server never has to connect to the cloud. See [Reaching it from outside](#reaching-it-from-outside).
