All work

Realtime streamer platform · Design · Backend

Omiros

A freemium hub for Twitch streamers — a customizable identity page, and Twitch and Discord bots that push every event live to overlays. My flagship: the largest system I've designed, built and run solo, in production.

01 · Why

One place instead of a dozen tools

Streamers juggle a dozen separate services. Omiros pulls the important ones into one place: a bento page they make their own identity, community events like subgoals, and bots that react to what happens on stream in real time.

It's freemium, and it's the project where I forged the backend blueprint the rest of my work now reuses.

02 · The realtime spine

"Realtime" is easy to fake, so here are the actual transports

Twitch events arrive as EventSub webhooks. A Go core processes them. The pieces after that each use a different transport, chosen for its channel rather than for the buzzword.

  • Overlays in OBS receive updates over Server-Sent Events — one-way, because an overlay never talks back. SSE gives auto-reconnect and rides plain HTTP with no upgrade handshake, so a WebSocket here would be over-engineering.
  • The Discord bot runs on a persistent Gateway WebSocket.
  • Lower-stakes reads simply poll. Three transports, no cargo-culting.
03 · The decision I'm proudest of

Overlays run untrusted code, so they run somewhere else

Streamers can put arbitrary animation scripts into their overlays. So overlays are served from a separate, cookieless origin and rendered in a sandboxed iframe — a malicious overlay can't reach the session on api.omiros.me because the cookies simply aren't there. Most people would serve overlays from the same domain and get burned.

The same second-order thinking shows up elsewhere: banned words on public pages are blocked at save, so a troll can't get a streamer Twitch-banned through a page the streamer didn't even write.

04 · A trade-off on purpose

Full reload over clever patching

When an overlay updates, the page reloads in full rather than patching the DOM. It's a blunt instrument — it flashes, and it kills smooth animation — and I chose it knowing that.

Overlays update rarely (a sub, a follow, a milestone), run unattended for hours, and a frozen overlay mid-stream is a public incident. A full reload means the overlay is consistent with the backend by construction, with almost no client state to drift. Robustness over elegance, with the limit named out loud.

05 · Timeline

The expensive work was invisible — and I killed a finished feature

Most of the four and a half months went into things you can't see on screen: multi-tenant overlay security, the Twitch EventSub lifecycle, a billing rebuild.

I also deleted a finished feature. Subathon shipped as a complete, tested module — then I removed it wholesale. Not because the code was bad, but because I couldn't answer how the user should experience it, and building backend behind an undecided UX is building waste. I'd rather leave an honest gap than a bad foundation something else comes to depend on.

Method

How this comes together

I decide the architecture and enforce it; the code beneath is AI-written, and I read it back before it ships. Putting overlays on a cookieless origin inside a sandboxed iframe was a decision about untrusted code, not a snippet to generate — and understanding the output is what tells me it actually seals that boundary. Following the code closely is also how I catch a build heading the wrong way and steer it back before it drifts.

Available · remote

Want the same, shipped and run?

Three lines about your idea is enough. Reply within 24 hours.