The operating systemfor the modern home.
Rooms, energy, cameras and AI — one model of your home, for everyone who lives in it.
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.
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
Så
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.
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.
- 01
You are sent to Home Assistant
The login redirects the browser to Home Assistant's own login page. Alva never sees a password.
- 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.
- 03
The backend does the exchange
Tokens are minted server-side. The refresh token is encrypted and stays there.
- 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.
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.
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.
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.
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" \
alvaDemo 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