The operating systemfor the modern home.

Rooms, energy, cameras and AI — one model of your home, for everyone who lives in it.

Alva dashboard showing the 3D house, room controls and live status

Home Assistant is the kernel.
Alva is the operating system.

Home Assistant stays the source of truth for devices, states, areas, scenes and automations. Alva owns presentation and policy: layout, mappings, quick access, roles and audit.

6

Roles, enforced in the API

~30

Gated actions

3

Stream fallbacks per camera

1

Docker image, any instance

Capabilities

One surface for the whole house

Desktop and mobile are genuinely separate compositions. A phone app that feels like a phone app, not a website with a hamburger menu.

Rooms, scenes, climate

One room-state model shared by desktop, tablet and phone. No shrunk desktop view.

Live cameras

WebRTC, HLS, MJPEG — tried in order, plus stream quality fallback, so something always shows.

Energy that plans

The cheapest contiguous window for the dishwasher, laundry or car — computed by instant.

Local AI insights

A curated read-only snapshot to a local Ollama model. No tools, no execution.

The interface

Every surface, one house

The same rooms and the same data, composed differently for desktop, tablet and phone. Click any view to open it full size.

Rooms

Every room, one honest state

Temperature, humidity, lights and media per room — and a blank where there is no sensor, instead of an invented number.

Climate

Zones you can actually steer

Dial per zone, measured against target, with heat, cool, auto and fan speed one tap away.

Mobile

A phone shell, not a shrunk desktop

Five tabs — Hem, Rum, Kameror, Energi, Mer — composed for 390 pixels, sharing the same room-state model as the desktop.

Energy

Spot prices, turned into a plan

The cheapest contiguous window for the dishwasher, the laundry or the car — computed by instant, and honest about when tomorrow is not published yet.

Cameras

Live, or an honest reason why not

WebRTC first, then HLS, then MJPEG, then the other stream quality. Every media byte passes a session-gated proxy.

Live video

A chain, not a choice

What Home Assistant advertises and what a camera delivers are not always the same thing — so a camera that reports WebRTC and then fails to connect still ends up showing video.

WebRTCSub-secondgo2rtc in Home AssistantThe only transport that can carry audio to the camera — what the talk button uses.
HLSA few secondsHA stream componentWorks for any streaming camera with no extra setup.
MJPEG1–2 fpsNothingLast resort. HA re-encodes one frame at a time.
And a second dimension, tried first: the entity. An H.265 main stream is unplayable in a browser, so the player tries the substream before it gives up on live video — a smaller picture beats a slideshow.

Keyed on the situation,
not on the moment.

A condition that holds for an hour notifies once, and notifies again only after it has cleared. Delivery is web push straight from your own server: the VAPID keypair is generated on first boot, payloads are encrypted to each browser's own keys, and Apple's and Google's push services relay ciphertext only.

Automations

Four questions instead of YAML

Alva has no automation engine and deliberately never will. A rule made here is afterwards indistinguishable from one made in Home Assistant's own editor.

När

When

the front door opens

Om

If

nobody is home

Then

turn on the hall light

Till vem

To whom

notify the adults

The rule is printed underneath as a plain Swedish sentence, then written through Home Assistant's config API — HA validates it, reloads it, and its rejection message comes straight back to you.

Architecture

A monorepo with one direction of trust

Entity state reaches the browser as a snapshot followed by diffs. The only way to change anything is a single audited service call.

Browser

React 19, Vite, Three.js, Framer Motion. A static SPA that receives state as a snapshot followed by diffs.

API

Fastify. Sessions, permissions, configuration, the HA adapter, journal and audit log.

Schemas

Zod schemas shared by both — versioned config, room mappings, roles, pure logic.

Browser
SSE state stream
Alva API
Home Assistant

Reads stream from one endpoint; writes go through a single audited call, with permissions resolved from the service domain and recorded once Home Assistant confirms them.

Identity

There is no token to paste

Sign-in goes through Home Assistant rather than around it. The house's identity provider is the house.

  1. 01

    You are sent to Home Assistant

    The login redirects the browser to Home Assistant's own login page. Alva never sees a password.

  2. 02

    It redirects back with a one-time code

    The callback lands on the server, not the browser — the code is never exposed to page scripts.

  3. 03

    The backend does the exchange

    Tokens are minted server-side. The refresh token is encrypted and stays there.

  4. 04

    The browser gets a cookie. That's all.

    Opaque, HttpOnly, SameSite=Lax, Secure. The stored value is hashed, so a database copy can't be replayed.

Security

The house is not a demo environment

Every decision here answers the same question: what can a browser on your network actually reach?

Home Assistant is the identity provider

Sign-in goes through HA. Alva never sees a password, and there is no long-lived token to paste anywhere.

No Home Assistant token in the browser

The long-lived token lives server-side only — the API socket and the camera proxy use it; nothing served to a browser contains it.

Opaque session cookie

HttpOnly, SameSite=Lax, Secure in production. The stored value is hashed, so a database copy cannot be replayed.

CSRF token on every write

State-changing requests must echo a token fetched from the server in a custom header. A cookie alone is not enough.

Camera bytes are session-gated

Every media path carries an auth check, and the routes that hand out stream URLs are bounded to cameras in the saved configuration.

The model is sandboxed by construction

A curated read-only snapshot in, at most five short lines out. No tools, no token, nothing executed.

Household

A home has more than one user

Six roles and around thirty gated actions, enforced in the API. Hiding a control in the frontend is presentation, never authorization.

OWNERADMINADULTCHILDGUESTAI_SERVICE

Owner is not the HA admin

The first Home Assistant admin to sign in adopts the pre-seeded OWNER account. Everyone else becomes ADULT — an HA admin does not silently inherit this app's configuration.

Your layout, your account

Which cards appear and in what order is per account, not per household — arranging your own start page is not an administrative act.

Even the AI has a role

AI_SERVICE is a first-class account with its own permissions — the assistant is subject to the same gate as everyone in the house.

Reasoning

How it decides things

Three places where the argument matters more than the code — and why none of it is the model's job.

01

Nothing scrolls sideways on a phone

Every desktop page is also a mobile sub page, so each has to survive 390 pixels. A headless check runs on every push.

02

Cheapest window, by instant

Windows are contiguous by instant, not by hour label. Tomorrow joins once the day-ahead auction publishes; before that the card says so.

03

Median and MAD, not mean and sigma

Normal is learned per hour of the day. One December with the heating stuck on would inflate a mean and blind the detector.

Deploy

One image, any Home Assistant

HA_URL and HA_TOKEN are read at container start, not baked into the image — so the same build runs against any instance.

docker build -t alva .

docker run -d --name alva -p 8088:80 \
  -e HA_URL="http://homeassistant.local:8123" \
  -e HA_TOKEN="your-long-lived-token" \
  alva

Demo mode by default

With no credentials configured, the whole UI renders against a fixture that mirrors a real entity registry — 3D house, rooms, scenes, cameras and stats, all inspectable.

Proxmox, NAS or any Docker host

A small Debian VM, or an LXC with nesting enabled. A systemd timer compares the checkout against origin/main and rebuilds only when they differ.

Want to see it running?

Alva is a private project in active development. Get in touch for a walkthrough or access to the repository.

Request access