Rural Peds
Blog
← Back to Blog

WASM-Powered Clinical Computing: Rust in the Browser

Timothy Hartzog, MD||10 min readMDX
WASMrustclinical-computingarchitecture
Save offline
Part 1 of 2
Series: Building the Blog Platform
View series →

Why Rust + WebAssembly for Clinical Software?

Clinical decision support demands two things that rarely coexist: correctness and speed at the edge. The algorithms must be validated against published references, and they must run instantly — even on a nurse's tablet in a rural ED with no connectivity.

WebAssembly (WASM) lets us compile Rust code to a binary format that runs in any browser at near-native speed. No server round-trips, no network dependency, no cold starts.

iInfo

Every clinical calculation on this platform — drug dosing, sepsis scoring, growth percentiles, IVF prescriptions — runs locally in your browser via Rust → WASM. Zero data leaves the device.

The Architecture

Our computation pipeline flows through three layers:

🔬

sci-* Crates

Core scientific computation: units, statistics, growth curves, ODE solvers. These are domain-agnostic building blocks.

🏥

ped-* Crates

Clinical domain logic: dosing formularies, scoring algorithms, simulation engines. These consume sci-* and add medical context.

🌐

ped-wasm

The WASM boundary crate. Exposes all clinical functions to JavaScript with structured error envelopes and input validation.

⚛️

React Frontend

Calls WASM functions via hooks. The UI is a pure rendering shell — no clinical math in JavaScript.

Show Me the Code

Here's how the Phoenix Sepsis Score is computed in Rust. The entire organ dysfunction assessment — respiratory, cardiovascular, coagulation, neurologic — runs in microseconds:

#[wasm_bindgen]
pub fn scoring_phoenix_sepsis(inputs_json: &str) -> JsValue {
    use sci_clinical::pediatrics::scoring::phoenix_sepsis::{compute, PhoenixInputs};
    let inputs: PhoenixInputs = serde_json::from_str(inputs_json)?;
    let result = compute(&inputs)?;
    // Sepsis = PSS >= 2 with suspected infection
    // Septic shock = sepsis + >= 1 cardiovascular point
    serde_wasm_bindgen::to_value(&result).unwrap()
}

And the JavaScript side is trivially simple:

const result = wasm.scoring_phoenix_sepsis(JSON.stringify({
  respiratory: { pao2_fio2_ratio: 150, on_ventilator: true },
  cardiovascular: { lactate_mmol_l: 5.0, map_mmhg: 45 },
  coagulation: { platelets: 80000 },
  neurologic: { gcs: 12 },
}));
*Tip

The Rust compiler guarantees at compile time that every score carries a CITATION: ClinicalCitation constant with the source paper's DOI, authors, and geographic scope. A score without a citation won't compile.

Try It: Data Playground

The data playground below is powered by the ped-blog WASM module. Enter any numeric dataset and compute descriptive statistics, histograms, or normalization — all processed by Rust running in your browser.

Interactive Statistics Engine

Enter numeric data to compute descriptive statistics, histograms, and normalization using Rust WASM.

Rust WASM

Enter data and click a computation button to see results.

Performance Characteristics

| Operation | Input Size | WASM Time | JS Equivalent | |-----------|-----------|-----------|---------------| | Drug dosing (full formulary) | 5 drugs | ~0.1 ms | ~2 ms | | Phoenix Sepsis Score | 4 domains | ~0.05 ms | ~1 ms | | Growth percentile (WHO) | 1 measurement | ~0.02 ms | ~0.5 ms | | IVF prescription | Full context | ~0.3 ms | ~5 ms | | Descriptive stats | 1000 values | ~0.5 ms | ~3 ms | | Linear regression | 1000 points | ~0.8 ms | ~6 ms |

+Note

These benchmarks were measured on a mid-range laptop. On mobile devices, the difference is even more pronounced — WASM's predictable performance model avoids the JIT warmup variability that plagues JavaScript on constrained hardware.

Validation Under GAMP 5

All clinical computation runs under the Hartzog Enterprise Validation Framework v1.0, implementing ISPE GAMP 5 Second Edition with FDA Computer Software Assurance. This means:

  1. Risk-based testing — HIGH-risk functions (sepsis scoring, drug dosing) require ≥90% code coverage
  2. Reference-result regression — published examples from source papers become automated test cases
  3. Traceability matrix — every user requirement traces to a functional spec, design spec, test case, and code module
  4. Change control — every merge to main creates an immutable audit trail entry
# From validation/RISK_REGISTER.md — example risk entry
[risk.phoenix_sepsis]
category = "Cat5-Custom"
risk_level = "HIGH"
patient_safety_impact = "Direct"
coverage_threshold = 90
reference_paper = "JAMA 2024;331(8):675-686"

What This Means for Rural Medicine

!Warning

More than 60 million Americans live in rural areas where pediatric specialists are hours away. Clinical decision support that works offline isn't a nice-to-have — it's a patient safety imperative.

When a 3-year-old presents to a critical access hospital with altered mental status and a fever of 40.2°C, the rural provider needs:

  • Instant weight-based dosing — no mental math at 2 AM
  • Guideline-concordant scoring — Phoenix, not SIRS
  • Decision tree guidance — stepwise algorithms for rare presentations
  • All of it offline — because the hospital's internet just went down

WASM makes this possible. The entire clinical engine — every drug, every score, every algorithm — compiles to a 245 KB binary that caches in the service worker and runs without any network connection.

References

  1. Sanchez-Pinto LN, et al. Development and Validation of the Phoenix Criteria for Pediatric Sepsis. JAMA. 2024;331(8):675-686.
  2. NRP 9th Edition. American Academy of Pediatrics / American Heart Association. Circulation/Pediatrics. October 2025.
  3. ISPE GAMP 5: A Risk-Based Approach to Compliant GxP Computerized Systems, Second Edition. 2022.
ShareXBlueskyMastodonLinkedInEmail

Related articles

Neonatal Resuscitation by the Numbers: Interactive Data Visualization

1 shared tag

An interactive exploration of NRP 9th edition target SpO2 ranges, epinephrine dosing curves, and cord management decision data — powered by …

Get new articles by email.

Powered by mailto. Your address is never sold or shared.

Discussion

Comments are powered by Giscus via GitHub Discussions. Set NEXT_PUBLIC_GISCUS_* environment variables to enable them.