
For a long time, online health tools followed the same pattern:
• long forms
• slow web apps
• mandatory accounts
• and most importantly — data sent to a server.
I wanted to challenge that.
What if a user could calculate an educational health score — in this case, prediabetes risk — with zero data leaving their browser?
No backend.
No analytics.
No requests.
Just a clean JavaScript engine running locally.
That idea became the foundation of SugarRisk, a fully client-side metabolic risk calculator built with HTML, CSS, and plain JavaScript.
In this article, I’ll walk through the technical concepts behind the project: how the scoring model works, how the UI updates dynamically, and why running everything locally creates a better privacy experience.
⭐ Why client-side only?
Most calculators online use a backend because:
they store results
they run machine learning models
they require user accounts
they log everything
But for an educational risk score, none of that is necessary.
Client-side advantages
Instant feedback — no network delay
Zero data exposure — nothing leaves the device
Lower hosting costs — no backend server
Better UX — results appear instantly while typing
Full transparency — users can inspect the scoring model
This approach also aligns with modern privacy expectations.
⭐ Project structure
The entire app is built from only three core files:
index.html # Layout + form
script.js # Scoring engine + interactions
style.css # UI/UX styling
And that's it.
No framework.
No dependencies.
No build step.
Just clean browser-native code.
⭐ The scoring model (explained simply)
Any risk calculator needs:
Inputs
Weights
A scoring formula
A way to explain results
SugarRisk uses 15+ inputs such as:
age
BMI
waist circumference
physical activity
family history
blood pressure
sleep quality
smoking
sugary drinks
fasting glucose (optional)
A1C (optional)
Each factor contributes a weighted amount to a total score from 0 to 100.
For example, here's a simplified version of the waist logic:
function waistRisk(waist, gender) {
if (!waist) return 0;
if (gender === "male") {
if (waist < 94) return 0;
if (waist < 102) return 8;
return 15;
}
if (gender === "female") {
if (waist < 80) return 0;
if (waist < 88) return 8;
return 15;
}
}
Each component returns a partial score.
The total score is the sum of all components:
let totalRisk =
ageRisk(age) +
bmiRisk(bmi) +
waistRisk(waist, gender) +
activityRisk(activity) +
glucoseRisk(fastingGlucose) +
a1cRisk(a1c) +
lifestyleRisk(smoking, sugaryDrinks) +
sleepRisk(sleepQuality);
Finally, the score is normalized:
totalRisk = Math.min(100, Math.max(0, totalRisk));
⭐ Live updating with JavaScript
One of the nicest UX elements is that the score updates instantly when the user changes an input.
DEV-friendly code snippet:
document.querySelectorAll("input, select").forEach(el => {
el.addEventListener("input", () => {
const score = calculateRisk();
updateUI(score);
});
});
The function updateUI() animates the bar and updates the text:
function updateUI(score) {
const indicator = document.getElementById("riskIndicator");
const label = document.getElementById("riskLabel");
indicator.style.left = ${score}%;
if (score < 34) label.textContent = "Low Risk";
else if (score < 67) label.textContent = "Moderate Risk";
else label.textContent = "High Risk";
}
This gives users real-time feedback, which feels much more engaging than submitting a form.
⭐ Visualizing the score
The score bar is a simple linear gradient:
green → yellow → red
Matching metabolic risk zones.
CSS example:
.risk-bar-track {
height: 10px;
border-radius: 999px;
background: linear-gradient(90deg, #22c55e, #fbbf24, #fb7185);
position: relative;
}
.risk-bar-indicator {
position: absolute;
width: 16px;
height: 16px;
border-radius: 999px;
background: #b91c1c;
transform: translate(-50%, -50%);
}
The result:
Smooth
Minimal
Helps users understand their risk immediately
⭐ Privacy-first architecture
This is where devs usually raise an eyebrow:
“If there’s no backend, how do you store results?”
Answer:
You don’t.
There’s no reason for sensitive health information to leave the device.
No cookies
No local storage
No analytics
No request logs
No user accounts
Here’s the actual network tab during use:
(empty)
The scoring happens entirely inside a pure function:
function calculateRisk() {
// returns a number 0–100
}
Users can also inspect how everything works — something impossible in black-box medical apps.
⭐ Lessons learned
Building this tool taught me a few things:
✔ You don’t need a backend for everything
We often default to servers even when logic can run client-side.
✔ Transparency builds trust
Users appreciate seeing that no data leaves their browser.
✔ Simplicity > complexity
No frameworks = fast loading = great UX.
✔ Health-tech needs privacy-first tools
People are more likely to use health calculators when they know their data isn’t sent anywhere.
⭐ Try the demo
If you want to see the calculator in action:
You can view everything in DevTools — logic, UI, requests (or rather, the lack of them).
⭐ Final thoughts
This project started as a small experiment:
Can an educational health tool run entirely in the browser with zero data collection?
The answer was yes.
And I think we’ll see more privacy-focused micro-apps like this — fast, transparent, and user-friendly — especially as people become more aware of how their health data is used.
If you have ideas, improvements, or want to build something similar, feel free to connect. I'm always open to health-tech discussions.
Top comments (0)