[ Ionut Dumitru ]
SystemsJun 1, 20267 min read

Automating a home with local-first tools

A calmer, private smart home that keeps working when the cloud does not — and that you actually own.

Most smart home gear is a long-term bet that someone else's server will stay online, stay free, and stay interested in you. That bet keeps losing. A hub gets discontinued, an account gets a subscription tier, an API quietly shuts off, and a light switch you paid for becomes a brick. The product still works exactly as designed — the design just never included you keeping it.

I run my house the opposite way. Every device that matters speaks a local protocol, every automation runs on a small computer in a closet, and the internet is a convenience, not a dependency. When my upstream provider has an outage, I find out from a news site, not from my own lights. That is the whole point: a home that keeps its promises whether or not a company on another continent is having a good day.

Own the brain, not just the bulbs

The single decision that changes everything is where the automations live. Cloud platforms put the logic on their servers and leave you a remote control. Local-first inverts that. The brain — Home Assistant, in my case — runs on a Raspberry Pi-class box in the house. It holds the rules. The devices are just hands and eyes.

Once the brain is local, two things stop mattering: which brand made the device, and whether that brand still cares. A motion sensor is a motion sensor. I buy on the protocol, not the logo:

  • Zigbee and Z-Wave for sensors and switches — cheap, battery-friendly, no Wi-Fi congestion.
  • Matter where it is genuinely local, with a skeptical eye for the ones that still phone home.
  • Local HTTP or MQTT for anything custom I build myself.

The test I apply before buying anything: pull the network cable, then see if the device still does its one job. A bulb that won't turn on without the cloud is a bulb I return.

The seam is the system

The interesting work in a home isn't any single automation — it's the seams between them. A good automation is invisible. The hallway lights come up to twenty percent at 2am when someone walks through, because nobody wants full brightness at 2am, and nobody wants to think about it either. The thermostat eases back when the last phone leaves the house and recovers before the first one returns. None of these are clever. All of them are specific, and the specificity is the design.

This is where local-first quietly pays off again: latency. A cloud round trip means you flip a switch and wait while a packet visits a data center and comes back. Local, it is instant — the lag between intent and response is below the threshold where you notice. That sub-second gap is the difference between a gadget and an appliance.

A smart home succeeds the day everyone in the house forgets it is smart.

Automations should also fail safe. A smart switch must still work as a dumb switch when the brain is down — the wall control is sacred. If my partner has to open an app to turn on a light, I have built a worse light. The rule I hold myself to: every automated thing has a manual fallback that a guest could find in the dark.

Keep the data in the house

Privacy isn't a feature I bolt on; it falls out of the architecture for free. When the logic is local, the data is too. Motion timestamps, door events, when the house is empty — that is a precise map of my family's life, and I see no reason to ship it to a vendor's analytics pipeline so it can be retained, breached, or sold.

For the few things that benefit from intelligence, I keep that local as well. Camera detection runs on a small box on my own network — frames never leave the house. The trade is real: I do more setup and I own the maintenance. But the camera that decides whether a person is at the door does it in my hallway, not in a region called us-east-1.

The discipline that makes this maintainable is treating the config like code:

automation.yaml

- alias: Hallway night light
trigger:
  platform: state
  entity_id: binary_sensor.hall_motion
  to: "on"
condition: "{{ now().hour < 6 }}"
action:
  service: light.turn_on
  data:
    brightness_pct: 20

Plain text, in version control, diffable, and mine.

Every automation is a text file in a git repository. When something breaks, I read the diff. When I move to new hardware, I copy a folder. There is no proprietary format holding my house hostage, and no support ticket between me and a fix.

What it actually costs

I won't pretend this is free. Local-first asks for an afternoon of setup where a cloud app asks for ten minutes, and it asks you to be your own tech support forever after. You become the integrator. The reward is that the system gets better over the years instead of worse, because nobody can revoke a feature you already have or charge rent on a switch you already bought.

The cloud model optimizes for the first day — easy onboarding, a slick app, a quick win. Local-first optimizes for year five, when the company that sold you the slick app has pivoted, been acquired, or moved your feature behind a paywall. My house is on year five, and the lights still come up to twenty percent at 2am.

A home is not a product you use for a quarter. It is infrastructure you live inside for a decade. Build it on things you own, that work in the dark, and that answer to nobody but you.

#Systems#Smart HomeShare ↗
→ / AUTHOR
Ionut Dumitru
Ionut Dumitru

Full-stack engineer and product designer. Writes about building products where the engineering and the design are the same job.

→ / NEXT
AIMay 25, 2026
Notes on building with LLMs in production
← All writingionutdumitru.com