Skip to content
Architecture

From useEffect Chaos to Deterministic Systems: Why I Rebuilt Our Biometric Pipeline with a Finite State Machine

I deleted 40+ useEffects and replaced them with a Finite State Machine. That was the best decision I made for our biometric assessment pipeline.

Written by Montasim
3 min read

A deterministic state machine coordinating a real-time biometric assessment pipeline

From useEffect chaos to deterministic systems

I deleted 40+ useEffects and replaced them with a Finite State Machine.

That was the best decision I made for our biometric assessment pipeline.

Our movement assessment system runs real-time computer vision (MediaPipe Pose, TensorFlow.js MoveNet), WebRTC video recording, and Azure text-to-speech audio guidance — all simultaneously in the browser.

The problem wasn't the developers. It was the paradigm.

The original code managed this with scattered: useState + useEffect chains.

10 boolean flags. Race conditions everywhere. “Works on my machine” became the norm. State transitions had no boundaries. One missed flag flip = broken recording = lost patient data.

When your system has 10 distinct states, 19 events, guard conditions, parallel detection loops, and real-time pose estimation running at 60 fps, useEffect dependency arrays cannot model that reality. They were never designed to.

So I rebuilt the entire flow on a custom FSM architecture

A pure reducer function handles all transitions. Every state is explicit. Every event is named. Every transition is guarded.

A detection bridge pattern connects the 60fps pose pipeline to state transitions without stale closures.

A priority-based audio manager prevents instruction collisions.

Zero race conditions. Zero phantom states. Zero “How did we get here?”

Debugging dropped from hours to minutes

What used to take 3 hours to debug (tracing useEffect chains through 5 components) now takes 3 minutes. The state chart is the documentation. If the system is in RECORDING_MOVEMENT_VIDEO, I know exactly which 3 events can follow and which guards each one is.

A finite state machine doesn't just fix bugs. It's the architecture shift that separates “it works” from “it's reliable.”

The uncomfortable truth most frontend devs avoid

Not every state problem needs XState. Not every state problem can be solved with useState.

But when your UI orchestrates real-time ML inference, video encoding, and audio playback in parallel — and the cost of a state bug is a patient losing their assessment data — you need deterministic state transitions.

Working through a similar challenge?

Share your context, constraints, and timeline to start a focused conversation.

Discussion

Join the conversation about this article

0 comments

Loading discussion

Fetching the latest comments.

Leave a reply

Respond to the article or continue the discussion.

Ctrl + Enter to post

Your email stays private. Comments are stored securely.