The Michigan Unemployment Insurance Agency runs one of the largest claimant-facing systems in the country: 270,000 residents at peak, every one of them under financial pressure. The frontend that mediates that experience matters in a way most marketing software doesn't.
I worked on the React modernization of the claimant and caseworker portals. My primary contribution was accessibility: bringing the system into strict WCAG conformance across 2,000+ pages, alongside performance work on hot paths like the navbar, and a maintainability pass that pulled sprawling logic back into a single source.
Accessibility was the work
The system serves the most digitally vulnerable members of the state: low-vision users, screen-reader users, motor-impairment users on assistive switch devices, users on five-year-old phones over flaky connections. If the frontend doesn't meet them where they are, the entire benefit-delivery system fails for the people who need it most.
What that meant in practice:
- 3,000+ accessibility defects resolved across 2,000+ pages, against strict WCAG 2.1 AA conformance.
- Screen-reader flows optimized end-to-end. Landmarks, focus management, ARIA semantics, error association, and form-progress announcements continuous across the multi-step claim flow, not bolted on per-screen.
- Tab-navigation flows optimized as the default keyboard pattern, not as a checkbox audit at the end.
Performance, measured in milliseconds
The user base is on five-year-old phones over flaky connections. Time-to-load and time-to-interactive get measured in milliseconds because that's the difference between a claim that completes and one that gets abandoned mid-flow.
The biggest performance work was on the navbar, with a ~30% average improvement in time-to-load and time-to-interactive across the hot paths I touched. The wins came from two angles:
- Optimizing the caching layer so navigation transitions stopped re-fetching identical data on every screen.
- Collapsing O(n²) logic into O(n). Replacing nested loops with single-pass iteration that cached intermediate results, then read from cache. Significant relief on the caseworker-side pages with large data sets.
Maintainability: pulling the sprawl back into one place
Long-running public-sector codebases accumulate the way you'd expect: sidebar logic duplicated across screens, prop drilling four or five levels deep, permissions state with no clear ownership. I led targeted detangling work alongside the accessibility pass:
- Sidebar code consolidated into a single source, eliminating the per-screen forks that had drifted apart over the years.
- Modern React hooks throughout, replacing the older class-component patterns the codebase had inherited.
- Context state for user permissions so any component could read the active user's permissions from a single lookup at the auth boundary instead of N redundant calls across the tree.
The trade-offs
Public-sector frontend has constraints most product engineers never see: a regulatory surface that constrains every change, a release cadence governed by audit cycles, a legacy backend you're not rewriting, and a user base where "use a different browser" isn't an acceptable answer for anyone. The accessibility work isn't a separable workstream. It's the entire thesis of the rebuild.