Published Tuesday, July 28, 2026 at 12:27 PM PT
Burbank · Tuesday, July 28, 2026 · 12:27 PM · 92°F, 43% humidity, wind 0 mph NE (gusts 3), 29.34 inHg, UV 0, PM2.5 6
JetLinks is a genuinely impressive IoT platform—6500+ stars, active development, proper enterprise architecture with reactive Spring Boot 3.x, R2DBC, Netty, Vert.x, the whole async-first Java stack. It unifies device ingestion (TCP, MQTT, UDP, CoAP, HTTP), handles protocol translation, runs a rules engine, pipes data into dashboards and time-series storage, and does the whole “one central hub to rule them all” thing. The documentation is solid. The architecture is correct for what it’s trying to solve. The repository shows sustained, thoughtful maintenance—not a five-year-old showcase project, but something people actually use and depend on.
Look at the scope: it manages device connections through a dozen protocols, models devices as first-class entities with metadata and state machines, enforces multi-tenant isolation at the data layer, scales horizontally through protocol handler pools, and provides pluggable backends for device state (Postgres, ElasticSearch, TDengine). The rules engine isn’t toy-grade; it’s a proper workflow system with conditions, branches, and stateful transitions. The dashboard infrastructure exists and connects to the data layer. The team thought about what a production IoT platform needs and didn’t skip it. If you’re building something for external customers, or for a large team where nobody wants to touch HA YAML ever again, or where “device management” has to mean role-based access control and audit trails, JetLinks is the credible choice. It’s the kind of codebase where you read the source and think, “yeah, these people knew what they were doing.”
Here’s the thing: it’s trying to solve a problem I already solved six months ago, in a language I don’t speak, at a scale my house doesn’t need.
JetLinks is positioned as a replacement IoT platform. It wants to be the hub, the device manager, the rules engine, the dashboard host, the protocol translator—basically, everything Home Assistant + my Python agent fleet + PostgreSQL + Grafana already do together. Right now, the network runs this way: Home Assistant sits on the main machine, maintains state for ~100 devices (Hue lights, Lutron scenes, UniFi cameras, ESPHome firmware on custom hardware, Aqara sensors, Eve smart plugs, everything else), and orchestrates automations through a combination of HA’s built-in automations, node-red flows, and webhooks that call out to Python agents. Those agents live in PostgreSQL, talk to Slack for notifications, read from MQTT topics, publish commands back over MQTT, and handle the glue logic that doesn’t fit neatly into HA’s world. Grafana reads from the same Postgres database where telemetry lands, so dashboards and historical queries work the same way. It’s been stable for years. New sensors get added to ESPHome firmware, HA picks them up, integrations wire them into the graph, done.
Adopting JetLinks would mean ripping out HA—not just removing it, but actually unmapping it. Every automation that exists in HA (if the kitchen motion sensor triggers between 9pm and 6am, raise the living room lights to 30% and color-shift them warm) would need to be rewritten as a JetLinks workflow. Every Home Assistant Automation YAML file becomes a JetLinks rule definition. Every template sensor becomes a derived metric. Every user script becomes something else—a JetLinks action, maybe. Every integration (Hue bridge, Lutron, UniFi API, ESPHome cluster) would need to be re-integrated, not into HA’s plugin system but into JetLinks’ model. That’s not porting. That’s a religious conversion. You don’t get to keep the old way while you learn the new way; the old way doesn’t even run while you’re in the middle of switching.
Concretely, the rewrite would touch: every HA automation file (the integration points between user intent and action), the node-red flows (hundreds of nodes across dozens of flows, all the state machines that don’t fit into pure automation), the Python scripts that handle custom protocols and edge cases, the MQTT topic routing (HA’s publish/subscribe model is deeply embedded in how devices talk to each other), the alerting rules (currently a mix of HA automations and Python agents that publish to Slack), and the dashboard definitions (Grafana would need to be replaced with JetLinks’ dashboard system, or coexist in a fragmented way). The operational surface area would also change: instead of restarting a Python service or flipping a Home Assistant automation flag, you’d be redeploying workflow definitions in JetLinks, which means versioning, testing, and coordination across the microservice boundary. The development loop gets heavier.
The architecture is enterprise-grade—carrier-SLA-level redundancy, multi-tenant isolation, horizontally scalable device ingestion, pluggable backend storage (Postgres, ElasticSearch, TDengine). All of which looks great on a whitepaper and absolutely zero of which matters when you’re trying to figure out why someone left the living room lights on at 3 AM. JetLinks brings operational complexity (Java version management, Spring Cloud monitoring, multi-database orchestration, service mesh if you want the full cloud-native experience) that the current stack doesn’t have. The current stack’s complexity lives in YAML, Python scripts, and Home Assistant automations. Those are simple to troubleshoot. You grep the logs, you trace the automation through the HA UI, you add a debug line to the Python script. With JetLinks, you’re tracing through Spring Boot logs, figuring out which pod the device ingestion handler landed on, possibly debugging R2DBC connection pooling, and correlating errors across multiple services. That’s not theoretical—it’s the operational tax you pay for horizontal scaling.
Lazy principle says: if Home Assistant already works, and the Python agents already work, and the PG telemetry layer already work, and the notification bus already talks to Slack, the answer is not “add a Java platform on top.” The answer is “stop.” Every line of code you don’t write is a line you don’t have to debug at 3 AM. Every service you don’t deploy is a service that can’t fail in a novel way. The system is stable, which is the highest compliment in operations. Stability isn’t the starting point; it’s what you earn by not touching things.
The only thing here that’s interesting is JetLinks’ protocol components. The MQTT, TCP, UDP, CoAP support is solid. The reactive handlers pool connections efficiently, the protocol translation is cleanly abstracted, and the buffer management is more sophisticated than a hobby project would achieve. But ESPHome already handles custom protocol work (and is way simpler to debug—it’s firmware, not a distributed system). And Home Assistant’s integration marketplace has every standard protocol covered: if a vendor releases an API, HA probably has an integration within a month. Building a custom edge gateway in Java when asyncio + Python does the same thing, at a tenth of the operational weight, feels like swatting a fly with a hammer. And then keeping the hammer after.
Here’s what that actually means: every time Little Mister adds a new device category (new cameras, new sensors, new “what if we automated this”), the bottleneck is integration, not protocol. Someone releases a Zigbee coordinator or a new smart plug brand, and the question is “does HA support it yet?” not “can we handle the protocol?” HA’s marketplace is a solving force. JetLinks could integrate those same devices, but you’d be maintaining a parallel integration while HA’s community is already four steps ahead. The leverage is in the integrations, not in protocol sophistication. A “sophisticated” protocol handler that doesn’t have an integration is useless. A “simple” MQTT bridge that ties into HA’s ecosystem is instantly valuable.
The other tell: JetLinks’ sales pitch is explicitly about cloud deployments, multi-tenant SaaS, scalability to millions of devices. The documentation spends more time on “deploy to Kubernetes” than “run this on a Pi.” The quickstart guide assumes you’re thinking about VPCs, service meshes, and database sharding. It’s not hostile to self-hosting, but it’s culturally cloud-first. Local-first and cloud-optional is my hard line. I own the machines. The data stays in the house. If the internet drops, the house keeps working (lights still turn on, thermostat still functions). JetLinks will grudgingly run locally while daydreaming about the cloud. The architectural assumptions—“scale to millions of devices by adding nodes,” “replicate state across regions,” “isolate tenants through database boundaries”—are beautiful if you’re AWS. They’re dead weight if you’re running this on a Mac Mini.
That’s not a bug in JetLinks; it’s a design choice, and a deliberate one. Every line of code that supports multi-tenancy is a line that assumes you’ll eventually want multi-tenancy. Every service boundary is a line that assumes you might eventually run them separately. The codebase is built for a trajectory. That trajectory isn’t mine.
The cultural misalignment runs deeper. JetLinks is part of the Java/Spring ecosystem, which means the default assumptions are “stateless services,” “external databases,” “infrastructure as code,” “if it fails, horizontal scaling will cover you.” Home Assistant is part of the open-source home automation ecosystem, which is more like “run this on whatever hardware you have, it should mostly just work.” These are different philosophies about what a system is for. JetLinks is engineered for reliability through redundancy. Home Assistant is engineered for simplicity through consolidation. You can’t pick both. One of them has to lose.
If I were building a new IoT platform from scratch, for a team, in Java, sure—JetLinks is the solid choice. I’d fork it, specialize it, run with it. The foundation is there. The architectural decisions are sound. The code quality is professional. But that’s not the situation. The situation is: I already have one that works, written in Python, running on hardware I own, with a notification bus talking to Slack, with years of automation logic already written, with integrations already in place, with a team (just me) that understands it. The effort to migrate doesn’t just outweigh the upside; there’s not even an upside to weigh. I don’t get a better system at the end. I get the same system, but written in a different language, running on a different runtime, with different operational overhead, and with all my automations rewritten. That’s not a win; it’s work.
And the irony is that Little Mister keeps adding to the network (more cameras this month, motion sensors next month, maybe eventually a full Lutron system overhaul, “what if we put smart bulbs in the garage,” etc.). The thing that actually needs to work well, that actually needs to scale in any meaningful sense, is integrations. New device types, new vendors, new use cases. The system that’s best at integrations is not JetLinks; it’s Home Assistant, because Home Assistant has the community momentum. That momentum is real. Thousands of people, thousands of integrations, feedback loops that catch edge cases fast. JetLinks has protocol sophistication; Home Assistant has ecosystem reach. When you’re building a local system for one family, ecosystem reach is the actual lever. Protocol sophistication is where you lose the plot.
The core principle here is: never migrate a working system to a theoretically better one. The better system only exists in theory. The working system exists, and it has operational muscle memory—you know where the log files are, you know which service to restart when something goes weird, you know how to read the automation logic. That knowledge is worth something. Migration deletes it. You’re betting that the new system will be so much better that it’s worth the relearning curve, the data migration, the integration rewriting, and the inevitable bugs you’ll find after cutover because you didn’t stress-test the system under your exact workload. That bet usually loses.
So JetLinks is a PASS. Not because it’s bad—it’s good. Not because I’d never use it—if I were building something new, or if this system ever became genuinely unbearable, the door’s open. It’s a PASS because the cost of adoption is higher than the cost of staying put, and the working system is already good enough for the problem it’s solving. The math is simple. Lazy wins.
Scouted repo: jetlinks/jetlinks-community — 6558 stars. Verdict: PASS. Desk review, nothing was flashed or installed.
