Skip to content

beaktech/beakwatch

Repository files navigation

BeakWatch

A kiosk display for BirdNET-Go. Shows live bird detections, species spotlights, rare visitors, daily top birds, and local weather on a rotating full-screen hero panel. Designed for a wall-mounted screen/iPad to show your live detections and statistics in a beautiful way, without any interaction necessary.

This may just be so you can have a nice display at home for your family. But works particularly well in public places. Maybe you want to promote awareness of birds to those in the area and you could even place a screen in your front window to show the neighbours the wildlife they are living with!

Note: Beakwatch is built as a fixed-layout for large screens (≥1280px wide) and iPads in landscape. It does not have a responsive mobile layout.

Screenshots

Last identified Species profile Activity patterns Most popular species Rare visitors

Features

  • Live detections sidebar — newest detection per species, deduplicated.
  • Rotating hero — last identified, species spotlight, top 10 over 30 days, 6 rarest visitors, today's species hourly chart.
  • On-demand bird images — fetched from Wikipedia the first time a species appears, then cached on disk forever. The repo ships zero images.
  • Local weather — current conditions from Open-Meteo (no API key).
  • Multi-server support — point at one or several BirdNET-Go instances and switch between them from the UI.

Prerequisites

  • Node.js 20+ (uses global fetch).
  • A reachable BirdNET-Go instance with the v2 HTTP API enabled.

Quick start

1. Clone and install

git clone https://github.com/beaktech/beakwatch
cd beakwatch
npm install

2. Create your config

Copy the example file to server/.env (note the server/ subfolder — that's where the app reads it from):

cp .env.example server/.env

Open server/.env in an editor and set at least BIRDNET_GO_URL to your BirdNET-Go instance, including the http:// prefix and port:

BIRDNET_GO_URL=http://192.168.1.10:8080

Everything else is optional — see Configuration below. (Running more than one BirdNET-Go? Use BIRDNET_GO_URLS instead.)

3. Build and run

npm run build   # compile the frontend into dist/
npm start       # serve the app + API

Then open http://localhost:2325 in a browser.

Just want to develop/tweak the UI? Skip the build and run npm run dev instead — see Development.

Configuration

All config lives in server/.env (see .env.example).

Variable Default Description
BIRDNET_GO_URL (unset) URL of your BirdNET-Go instance, e.g. http://192.168.1.10:8080. Required.
BIRDNET_GO_URLS (unset) Comma-separated URLs for multiple instances. Overrides BIRDNET_GO_URL.
BIRDNET_GO_NAMES hostname Comma-separated display names matching BIRDNET_GO_URLS (e.g. Garden,Office).
LAT 51.5074 Latitude for the weather widget.
LON -0.1278 Longitude for the weather widget.
PORT 2325 Port the kiosk server listens on. Dev mode proxies to this too.

Architecture

Browser  ──/api/*─▶  Express (server/index.js)  ──▶  BirdNET-Go (REST)
                          │
                          ├──/birds/*─▶  cache/birds/  (disk)
                          │                    │ miss
                          │                    ▼
                          │              Wikipedia REST API
                          │
                          └──static────▶  dist/  (built React app)
  • Express (server/): proxies BirdNET-Go, serves the built frontend, and runs the on-demand image cache.
  • React + Vite (src/): the kiosk UI. Tailwind for styling, Vitest for tests.
  • Image cache (server/birdImages.js): on a request for /birds/<slug>.jpg?name=<commonName>&w=<width>, serves from cache/birds/<slug>-<width>.jpg if present; otherwise hits Wikipedia for the species summary, downloads the sized thumbnail, writes it to disk, and serves it. Concurrent requests for the same image are deduped; outbound traffic is capped at 2 concurrent requests with backoff on HTTP 429.

The cache/ directory is gitignored and grows organically as new species are detected (~50–200 KB per species).

Development

npm install
cp .env.example server/.env
npm run dev    # vite (5173, or next free port) + nodemon-watched express (2325)

Vite proxies /api and /birds/*.jpg to Express, so you don't need a separate build. Open the URL Vite prints on startup (usually http://localhost:5173).

Scripts

Command What it does
npm run dev Vite + Express in watch mode
npm run build Build the React app to dist/
npm start Serve dist/ and the API from Express
npm test Run the Vitest suite once
npm run test:watch Vitest in watch mode

Trust model

Beakwatch is designed for a trusted LAN and has no authentication. Specifically:

  • The /api/server POST route lets any client on the network switch the active BirdNET-Go instance.
  • The /birds/*.jpg route lets any client trigger Wikipedia downloads and disk writes to cache/, and the ?name= parameter controls which Wikipedia page an image is cached from — so a client could fill the disk or poison cached images.

If you expose Beakwatch beyond a network you trust, put it behind a reverse proxy with auth, or gate these routes yourself.

Contributing

Issues and PRs are welcome. Before opening a PR, run npm run lint && npm test — CI runs both plus a build.

Attribution

Bird photos and summaries come from Wikipedia and Wikimedia Commons. Each photo is displayed with its photographer credit and licence (src/components/Attribution.jsx). Keep this attribution visible — it is the licence requirement for reusing those images.

Weather data from Open-Meteo under their terms of use.

License

MIT — see LICENSE.

About

A kiosk display for BirdNET-Go. Shows live bird detections, species spotlights, rare visitors, daily top birds, and local weather on a rotating full-screen hero panel.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages