---
title: Overview
description: One app for your cameras and recorders, through a small server on your own network.
---

Kestrel is one app for your cameras and recorders: live view, recordings,
events and each one's health, from any browser or as an app on your phone. It
talks to each system directly, so nothing goes through a vendor's cloud and
old hardware stays useful after its own apps stop working.

It starts with Raysharp-made recorders, which Swann, Lorex, Night Owl and
others sell, and whose own apps and plugins have stopped working in modern
browsers. Reolink cameras, a Bambu Lab printer's camera, any stream address
and recording to your own disk are on the way, as
[timmo001/kestrel#11](https://github.com/timmo001/kestrel/issues/11) sets
out.

A small server sits between your cameras and the page. Browsers can't open a
recorder's control port or play its RTSP streams, so the server holds the
sessions, passes on what they report, and runs go2rtc for the video. See
[Running it](/running) to set it up.

## What it does

- **Sources:** each source's connection and, for the recorder, its clock,
  its disks, and each camera's signal, recording mode and motion.
- **Recordings:** which days have recordings, and each day's clips on a
  channel, with why they were recorded (motion, PIR, alarm or normal) and
  their size. The player is laid out as the recorder's own client lays out
  playback: the video, its controls (stop, a frame at a time, speed up to 32
  times, the recordings either side, cut, a still, download, the same zoom
  as Live (fit, fill or a step at a time, only for the visit) and full
  screen, each with a key, listed under the help button), then a timeline of
  the day that zooms to ten minutes, where a
  click plays from that moment. Playback runs on from one recording into the
  next, any stretch of a day saves as an MP4, and the page remembers where it
  was, its speed and its timeline zoom in the browser. Up to four cameras play
  together on one clock, ticked in the camera picker: each one that recorded
  at that moment plays, the rest show a placeholder until their next
  recording, and the timeline has a track for each. They play the full
  stream while the recorder keeps up, about 14 times real time across them,
  and the sub stream past that.
- **Pages:** Live, Recordings, Events and Sources each have an address of
  their own, such as `/recordings?camera=swann/1&date=2026-11-11`, or
  `/recordings?camera=swann/1&cameras=swann/1,swann/3,swann/4&date=2026-11-11`
  for several cameras together. A camera's id is its source's and its own,
  such as `swann/3` for the recorder's channel 3. Older addresses by channel
  number still work.
- **Events:** motion, PIR, video loss and disk events as each source reports
  them, and today's motion and PIR clips found by search.
- **Live view:** the cameras with a signal through go2rtc, all at once (A,
  shown as the count and All) or any number fewer at a time (from the sub
  stream past four), paged with Previous and Next (Page Up and Page Down) or
  picked from the page list, which names each camera when there's one at a
  time. All is the default. The arrow keys move the pick around the page and
  on to the next page past the edge. Each picture keeps its shape, fitted
  whole into its tile. The zoom controls act on the picked camera, and each
  camera keeps its own zoom, once in the tiles and once on its own (so one
  zoomed in its tile still shows whole alone). It zooms 25% at a time (+, -
  and 0 to fit it whole), with Fill, where the picture covers its tile, one
  of the steps, so Fit or Fill (Z) jumps between whole and covering. Ctrl
  and the wheel or a pinch zooms the one under the pointer,
  and a drag moves around any picture
  bigger than its tile. Pause closes
  the streams and holds the last frames; a double click or Enter shows the
  picked camera alone, and Esc or Backspace goes back. S saves a still of it,
  and ? shows or hides the keys. The layout, the picked camera, each camera's zoom
  and how many cameras there were are kept in the browser, so the loading
  placeholders already sit where the cameras will.

## Parts

| Part                         | What it is                                                        |
| ---------------------------- | ----------------------------------------------------------------- |
| `packages/core`              | What every source shares, in TypeScript with Effect               |
| `packages/protocol-raysharp` | The Raysharp recorders' control protocol                          |
| `packages/source-raysharp`   | Raysharp recorders as a source, over that protocol and their RTSP |
| `packages/protocol-baichuan` | Reolink's own protocol, for replaying recorded files              |
| `packages/server`            | The server: the [API](/api) and go2rtc                            |
| `packages/web`               | The web client, installable on a phone                            |
| `packages/cli`               | The `kestrel` CLI, with Code Mode and MCP for [agents](/agents)   |
| `docs`                       | This site                                                         |

## Machine-readable docs

| URL                                     | Use                                      |
| --------------------------------------- | ---------------------------------------- |
| https://kestrel.timmo.dev/llms.txt      | Compact page index                       |
| https://kestrel.timmo.dev/llms-full.txt | Full docs bundle                         |
| https://kestrel.timmo.dev/mcp           | Hosted MCP (search, page and navigation) |
| `/{route}.md`                           | One page as Markdown                     |
