Tinkr
IoT Platform / Embedded

Outcomes
Firmware writes from a browser tab over Web Serial. No PlatformIO, no Arduino IDE, no USB driver, no port selection.
When the HMAC pepper had to change, dual-pepper verification re-hashed each board on its next contact instead of forcing a physical factory reset.
Overview
Tinkr is an ESP32 platform for people who do not want to install a toolchain. Firmware writes to the board from a browser tab over Web Serial, the board is claimed to an account in the same flow, and from then on it is driven from a phone.
Behind that: dual-slot OTA with an MD5 check before the switch, so a bad update rolls back instead of bricking a board that may be across the house. Board identity is an HMAC-SHA256 secret under a server-side pepper. Hardware profiles (tank, garden, camera) change what a board is without changing how it is provisioned, authenticated, or updated.
Challenge
Getting an ESP32 running normally means PlatformIO or the Arduino IDE, a USB driver that may not match your chip, and a serial port you have to guess. Every one of those is a place a beginner quits. Tinkr had to move all of it into a browser tab without giving up OTA updates, device identity, or the ability to recover a board that took a bad flash.
Tech stack
Architecture
Key features
Browser Flashing
Web Serial writes firmware straight from a tab. No IDE, no driver install, no port guessing. The board is claimed to an account in the same flow that flashes it, so provisioning and identity happen once.
Self-Healing OTA
Dual-slot partitions with an MD5 verification before the switch. A failed or corrupted update boots the previous slot rather than bricking a board that is no longer physically reachable.
Hardware Profiles
One firmware base with swappable profiles (tank, garden, camera). The profile decides what the pins mean; provisioning, authentication, and OTA stay identical across all of them.
Lessons & tradeoffs
The hard part of hobby electronics is not the electronics. It is the forty minutes of driver installation before the LED blinks. Tinkr moves flashing into a browser tab over Web Serial, so the thing standing between someone and a working board is a cable, not a toolchain.
The challenge
A device flashed in someone's living room is a device you may never physically touch again. A bad update is not a bug there, it is a brick.
What I decided
I put OTA on dual-slot partitions with an MD5 check before the switch, so a failed update boots the previous slot instead of a broken one.
What I took from it
When the hardware is out of reach, design the recovery path before the happy path. The update mechanism deserves more engineering than the feature it delivers.
The challenge
Board secrets are hashed under a server-side pepper, and that pepper is the HMAC key. Changing it invalidates every stored hash at once, which would have locked out every board already in the field.
What I decided
I verified against the current pepper first and fell back to the retired one, re-hashing transparently whenever the old pepper was what matched, so boards migrated themselves on next contact.
What I took from it
Rotating a credential that physical devices depend on is a migration, not a config change. Lazy migration on next contact beats a coordinated cutover you have no way to coordinate.
The challenge
Middleware gated the page routes but not the API routes, and each API route was expected to authorize itself. Two of them shipped without doing so.
What I decided
I audited every route against one canonical gate, and deleted the endpoint that turned out to have no callers rather than fixing it.
What I took from it
A convention that is not compiler-enforced is a convention that will eventually be broken. If every route has to remember to authorize itself, one of them will forget, and the only open question is which one.