methodology
How steadyhandtest measures hand steadiness
A steady hand test built on the accelerometer already in your phone. Here's what it measures, how the raw signal becomes a score, how it was calibrated, and where the honest limits are.
What this measures
Every human hand shakes a little. Hold your arm out and try to keep it perfectly still — there's always a small involuntary motion underneath, somewhere around 8 to 12 cycles a second in a healthy adult. It's called physiological tremor, and most of the time it's far too small to see. You notice it when you're tired, wired on coffee, nervous, or trying to thread a needle.
steadyhandtest measures that motion — not with a clinical rig, but with the accelerometer already sitting in your phone, the same chip that knows which way is up when you rotate the screen. You hold the phone still for ten seconds, the sensor records how much your hand moves, and you get a steadiness score plus a picture of where your hand wandered.
That's the whole idea. The rest of this page is what happens underneath, because the interesting part was never the score — it's what you have to do to pull an honest number out of a phone that was never designed for this.
Why holding the phone, not touching the screen
The first versions didn't use the phone's motion at all.
The first version was an Archimedes spiral. You traced it from the center outward with a fingertip, and I scored how far each point of your trace strayed from the ideal curve — I built the whole pipeline, the spiral geometry, the deviation math, a live trace that shaded from green to red as you wandered off the line. Then I ran it on my own phone and it failed two ways at once. Your fingertip sits right on top of the line you're following, so you can't see where you're going. And dragging a curve on glass mostly tests whether you're good at dragging — not whether your hand is steady. I even retuned it for fingers, fewer turns and a looser tolerance, before admitting I was polishing the wrong idea.
Version two dropped the tracing: press and hold a single dot in the middle, draw nothing, just keep your finger still for ten seconds. Less awful — no path to chase — but it still measured the wrong quantity. A fingertip pressed to glass barely travels, and the little drift I recorded was as much the contact patch sliding as my hand shaking. A proxy for tremor, not tremor.
What both versions shared was the finger. The moment I stopped treating the screen as the input and started treating the phone as the instrument, it clicked. You're already gripping a sensitive motion sensor. Hold it still and let it feel the shake — nothing covers the screen, nothing to drag, no skill to game, and the only thing left to vary is the one I wanted to measure all along.
So the version that ships treats the phone itself as the instrument. Hold it in your hand and try to keep it still, and your tremor shows up as tiny rotations and translations of the device. The accelerometer feels them. Nothing touches the screen, so nothing blocks your view, and there's no gap between a steady-handed person and a shaky one except the thing we actually care about: how much the hand moves.
This is, as it happens, close to how tremor gets measured in research — accelerometers fixed to the hand, recording motion over time. We're just borrowing the accelerometer you already own.
Reading the sensor
The browser exposes device motion through the DeviceMotionEvent API. On most phones it fires somewhere between 30 and 60 times a second, handing back acceleration along three axes. We take the x and y components — the in-plane motion — and use them to push a ball around the screen.
iPhones add a permission step. Since iOS 13, Safari won't release motion data until you allow it, and the request has to come from a tap — so the begin-test button is what raises the prompt. Allow it once and the test runs. Android browsers don't ask; motion is there by default.
A caveat I'd rather put up front: phone accelerometers are noisy. Their noise floor runs from roughly half a milli-g to a couple of milli-g, which is the same neighborhood as a mild tremor. So the absolute numbers aren't lab-grade. What the test is good at is relative comparison — your steady hold against your shaky one, or your hand now versus your hand after three coffees. Treat it as a consistent ruler, not a calibrated scientific instrument.
The ball, and why it drifts back to center
Here's the part that took the most fiddling. When you hold a phone, you don't hold it level. You hold it at whatever angle is comfortable, and that angle creeps as your arm tires. If the ball just answered to absolute tilt, it would bury itself in a corner the second you tipped the phone, and you'd spend the test hunting for level instead of holding still.
The first time I ran the tilt version on my own phone, the ball was unusable. I'd set the sensitivity to 60 — sixty pixels of travel per unit of acceleration — and the gentlest tip flung it to the edge of the screen, where it stuck and rattled against the boundary. Once it was pinned out there, I couldn't coax it back. One accidental tilt and the run was dead.
I fixed it in two moves. The first was recentering: instead of measuring against a fixed zero captured at the start, I let the ball's reference point chase my hand's recent average position with a time constant of about 1.2 seconds (I started nearer a second and a half and tightened it). Tip the phone and the center drifts after you; the ball eases back to the middle on its own, so you can always recover. In the code that's BASELINE_FOLLOW_TAU, and it's the single most important constant in the whole test.
The second move was admitting the sensitivity was just wrong. Even with recentering, a normal hold still smeared the ball across the entire canvas — far more motion than the rings could hold. I took it from 60 down to 15, tried again, then to 10, where it lives now. To avoid redeploying for every guess, I hid a tuning panel behind a ?tune=1 flag — sliders for both constants, updating live — and dialed the feel in on the actual phone, in my actual hand, reading the good values straight off the sliders.
In signal-processing terms, that recentering is a high-pass filter. We throw away the slow stuff — posture, drift, gross movement — and keep the fast stuff, the tremor. It also makes the test measure the right thing: someone who slowly tips the phone all over the place but has a rock-steady hand still scores well, because the slow tipping gets absorbed and their genuine hand motion is small. Which is correct. They're not tremoring.
From motion to a number
Across the ten seconds, we log the ball's distance from center on every frame. Four numbers come out of that:
- mean offset — how far from center the ball sat, on average.
- jitter — how much the ball jumped frame to frame. This is the closest thing to a direct tremor reading, because it catches the fast, small movements rather than slow drift.
- max excursion — the 95th-percentile worst moment, so a single fluke doesn't run away with the result.
- time centered — the share of the test the ball stayed near the middle.
The steadiness score is a weighted blend of those, leaning hardest on jitter, then squashed onto a 0–100 scale by a logistic curve. The whole thing is small enough to read in one block:
norm(x, μ, σ) = (μ − x) / σ
raw = 0.15 · norm(meanOffset, 16, 16)
+ 0.55 · norm(jitter, 6.5, 6)
+ 0.30 · norm(maxOffset, 30, 10)
score = round( 100 / (1 + e^(−1.2 · raw)) )
Jitter does most of the work because it's the cleanest signal. The slow offset gets eaten by the self-centering, so what's left is the real high-frequency motion — which is exactly what we're after.
How the score is calibrated
Here's where I want to be straight with you, because this is the easy part to fake and I'd rather not.
I had no population to calibrate against. No archive of thousands of holds, no clinical baseline — just one iPhone and one hand, mine.
So I did the only honest thing on offer: I ran the test three times on purpose. Once holding as still as I could. Once with a small deliberate shake. Once shaking hard enough to feel ridiculous. Each time I read the raw numbers off a debug panel — mean offset, jitter, max excursion. Steady came in around 0.8 pixels of mean offset and 0.3 of jitter; the hard shake, roughly 15 and 7. Then I set the scoring constants so those three runs landed where they belonged: 87, 73, 50. Jitter carries most of the weight, because it separated them cleanest — 0.3, then 2.4, then 6.9, almost tripling at each step.
That's the calibration. One person, one phone, one afternoon. I'd rather hand you that than dress it up as a population study it never was. As more people run the test the thresholds can shift toward real data; until then, the honest version is that this is tuned to my hand, and your score means the most measured against your own.
One reference point grounds the top of the scale, and it's the most useful one: a phone lying flat on a table, untouched, scores about 99. That's the closest thing to a perfect, tremor-free reading — no hand involved, just the sensor's own noise floor, which sits around 0.02 of jitter. A real steady hand runs noticeably higher, roughly 0.12 to 0.22. So the test isn't mistaking sensor noise for a steady hand: the motionless table lands clearly above any living hand, and your hold is measured against that floor. The machine at rest is the reference, and you're compared to it — which is about as honest as instrument-grounding gets.
So the brackets — Steady, Slight tremor, Notable tremor, High tremor — are reference points from the test's design plus that small amount of real tuning, not a clinical population study. They're descriptive labels for how much motion the sensor saw, nothing more. As the data grows, the ranges can be refined. Until then they're honest about being provisional.
The result page compares your score to an expected range for this test, not to any medical standard. That distinction is deliberate, and it matters.
One honest detail about the visualization
The motion we're measuring is tiny — a steady hold barely shifts the ball a couple of pixels. Draw that at true scale and you'd get a dot, and you'd learn nothing from staring at it.
So the on-screen ball and the trail it leaves are magnified, roughly six times, purely so you can see them. The score is computed from the real, un-magnified sensor values; only the picture is zoomed. It's the same trick as a seismograph — the needle swings hard so you can read it, but the quake itself was small. The number is honest; the drawing is amplified so your eye can follow along.
How you hold it, and why that matters
Here's the part the test can't do for you. How you hold the phone changes the motion the sensor sees. A phone braced against your chest, propped on a knee, or held tight to your body moves differently from one out at arm's length — different muscles, different leverage, a different shake. So two scores only really compare when the hold behind them was the same.
The hold I recommend is the one that shows postural steadiness most consistently: stand or sit, hold the phone in one hand, and stretch your arm straight out in front of you, unsupported, for the ten seconds. An extended, unsupported arm isn't leaning on anything to mask the motion, so you get a cleaner read of how steady the hand itself is. Extend it as the countdown runs out rather than holding the pose early — that way arm fatigue doesn't leak into the measurement.
And I'll be straight: the test has no way to enforce any of this. It can't tell how your arm was positioned, only how much the phone moved. The consistency is on you. If you want your scores to mean something — against yourself over time, or against someone else — hold it the same way every time. Same hold, comparable numbers. That's the whole trick.
What this is not
I'll say this plainly. This is a technical experiment in measuring motion with a consumer phone sensor. It is not a medical device, and it does not diagnose, screen for, or detect any condition. A score is a measurement of how much your hand moved across ten seconds, set against an expected range for this test — that is the entire claim.
This is not a medical diagnostic tool. If you are concerned about tremor, see a neurologist.
A neurologist has tools and training this page does not. steadyhandtest can tell you your hand moved more today than yesterday. It can't tell you why, and it won't pretend to.
References
- Critchley, M. (1949). Observations on essential (heredofamilial) tremor. Brain, 72(2), 113–139.
- Elble, R. J., & Koller, W. C. (1990). Tremor. Johns Hopkins University Press.
- Deuschl, G., Bain, P., & Brin, M. (1998). Consensus statement of the Movement Disorder Society on Tremor. Movement Disorders, 13(S3), 2–23.
- Kostikis, N., Hristu-Varsakelis, D., Arnaoutoglou, M., & Kotsavasiloglou, C. (2015). A smartphone-based tool for assessing parkinsonian hand tremor. IEEE Journal of Biomedical and Health Informatics, 19(6), 1835–1842.
- LeMoyne, R., Mastroianni, T., Cozza, M., Coroian, C., & Grundfest, W. (2010). Implementation of an iPhone for characterizing Parkinson's disease tremor through a wireless accelerometer application. Annual International Conference of the IEEE Engineering in Medicine and Biology Society, 4954–4958.