Project 01 / 05 · GE Healthcare · 2018–2019

Portrait Mobile, monitoring that moves with the patient

Portrait Mobile is GE Healthcare's continuous, wearable, wireless patient monitor — a smartphone-sized device on the patient streaming vitals to a bedside viewing station, designed to catch deterioration earlier than fixed bedside monitors by letting patients stay mobile through their stay. The product is FDA-cleared and HIPAA-regulated, in active use across ICU and step-down units. The engineering bar isn't “a smooth UI” — it's “a missed waveform second is a clinician's blind spot, and a leaked byte of patient data is a regulatory event.”

Role
Full Stack Engineer
Dates
May 2018 – Oct 2019
Location
Milwaukee, WI
Domain
Clinical / medical device
  • React
  • Canvas
  • WebSockets
  • TypeScript
  • Angular
  • NgRx
  • RxJS
  • Spring Boot
  • HIPAA
  • Jest
At a glance
Vitals streamed
SpO₂ · PR · RR

Continuous oxygen saturation, pulse rate and dual-vector respiration over hospital wireless.

Renderer split
Canvas + SVG

High-frequency waveforms on Canvas; clinician-interactive overlays on SVG above the Canvas layer.

Transport
WebSocket

Custom message protocol with sequence numbers, server-side replay buffer, and explicit gap markers when replay fails.

Regulated
HIPAA

Patient-identifiable data treated as a first-class front-end constraint — display, retention, log scrubbing.

The interface

Illustrative recreation

View product page ↗

An interactive recreation of the bedside viewer — built to convey the UI and engineering decisions, not the production code, which stays with GE Healthcare. The GE product page is linked above.

param.dev/ge-healthcare/portrait-mobile
Open full screen ↗

A resilient WebSocket protocol

Vitals stream wirelessly from the wearable — the protocol recovers from packet loss and reconnects without leaving continuity gaps in the waveform.

Canvas for high-frequency waveforms

SpO2 and respiration traces render on Canvas for throughput; lower-frequency overlays use SVG to keep the Portrait Central view interactive.

HIPAA enforced at the UI layer

Patient data handling rules are enforced in the front end itself, not just assumed to be handled upstream.

Recreation · faithful to the original UI behavior, not the shipped source.

The problem

Monitoring that can't blink — or tether the patient down

Portrait Mobile exists so patients don't have to stay tethered to a bedside box to be watched closely. A smartphone-sized wearable rides with the patient streaming oxygen saturation, pulse rate and dual-vector respiration continuously to a viewing station the clinical team watches — the goal is to catch deterioration earlier by letting patients move around the unit instead of staying wired down. The product is FDA-cleared, HIPAA-regulated, and runs in active ICU and step-down environments where clinical staff make care decisions off what the screen shows.

In that context the usual web tradeoffs change shape. Hospital wireless is not lab-grade — packet loss is the baseline reality, not an edge case. A reconnect that drops a few seconds of respiration data is a few seconds a clinician didn't see. Every byte on screen is patient-identifiable information, which means rules about where it can be displayed, how long it can be retained in memory, and what can be co-logged with it. The UI had to stay continuous under unreliable wireless, disciplined about what it displayed, and explicit about the moments when continuity actually fails.

A stutter in a waveform isn't cosmetic. A wireless reconnect that drops a few seconds of respiration data is a few seconds a clinician didn't see.
Why this project shaped how I treat the UI as infrastructure

Key decisions

Three choices that pinned the system down

The interesting work in Portrait Mobile lived in the constraints — unreliable wireless, regulated data, a clinician on the other end of the screen. Three architectural decisions did most of the load-bearing.

01Decision

Custom WebSocket protocol with packet-loss recovery

The wearable streams continuous oxygen saturation, pulse rate and dual-vector respiration over hospital wireless, which means occasional packet loss is the baseline reality, not an edge case. Vanilla WebSocket recovery would reconnect after a drop but leave a silent gap in the waveform — clinically unacceptable for a tool a nurse watches to catch patient deterioration. I designed the message protocol with sequence numbers, server-side buffering with replay on reconnect, and an explicit “gap detected” marker that the UI renders whenever replay isn't possible — so the absence becomes visible instead of hidden.

The catch· More protocol surface than a plain WebSocket reconnect. In exchange, the waveform on a clinician's screen is continuous, and the moments where continuity actually fails are explicit instead of silent.

02Decision

Canvas for high-frequency waveforms, SVG for everything around them

Waveform traces update many times per second across multiple channels. Rendering them through React → DOM → SVG would saturate the main thread under any realistic patient load. They render on Canvas, where draw throughput is much higher and rendering doesn't fight React's reconciler. Lower-frequency overlays — alarm flags, measurement labels, clinician annotations, deterioration markers — render in SVG above the Canvas, because the work there is interaction (clicking a flag to acknowledge, hovering for context) where DOM ergonomics win.

The catch· Two rendering technologies sharing one view is more code than a single approach. In exchange, neither layer is doing work it's slow at, and a clinician's screen stays smooth during a multi-channel viewing session.

03Decision

Patient-data handling enforced at the UI, not assumed upstream

Patient-identifiable information carries rules — where it can be displayed, how long it can be retained in memory, what it can be co-logged with, what gets scrubbed from any client-side log or error report. A typical web architecture assumes the back end has handled all of this, which is fine until a debug overlay, a crash report, or a screenshot for support quietly carries protected data somewhere it shouldn't be. The front-end stack treats it as a first-class constraint: scoped data storage, no retention beyond the visible session, an error-reporter pipeline that scrubs known-protected fields before any payload leaves the browser, and audit-trail markers on every component that displays patient information.

The catch· More discipline in every component that touches patient data; more upfront design on what counts as protected. In exchange, regulatory compliance becomes a property the front end actually owns, not a hope that someone else handled it.

What I built

The viewer, the workflow apps, and the services behind them

I built the front end of the bedside viewer — the React + Canvas + SVG composite that renders continuous vitals from the wearable. That includes the WebSocket client and the protocol implementation (sequence numbers, server-side replay buffer, gap markers when replay isn't possible), the Canvas waveform renderer, the SVG overlay layer for clinician interactions (alarm flags, deterioration markers, measurement labels), and the patient-data-aware layer that enforces retention and logging rules at the component level.

Alongside the viewer, I built Angular workflow apps for the surrounding clinical staff — NgRx for the application state, RxJS for the streaming data flows, OnPush change detection for predictable update behavior in a regulated UI. On the back end I built Spring Boot microservices feeding wearable medical-device data into the platform, with type-safe contracts at the API boundary and patient-data handling enforced end to end. The whole stack was Jest-tested under TDD — medical-device software does not have a “we'll fix it after a customer reports it” option.

Project 02 / 05 · Next

PG&E — Community Wildfire Safety Map