Inspiration
Someone has a concussion. They see a doctor, who tells them to rest, ease back into activity slowly, and come back in two weeks.
Then they go home. And for two weeks, they are on their own.
They try a fifteen minute walk. The dizziness gets worse. The next day they try again and it's a little better. On the third day their head hurts. All of this happens, and all of it is forgotten.
Two weeks later, in the consulting room:
"How has your recovery been going?"
"Better, I think. Some days worse."
That answer is honest and nearly useless. The information that would actually help a clinician — what activity was attempted, what the symptoms were before, what changed afterwards, on which day — happened weeks ago and was never written down.
Meanwhile the framework that guides concussion recovery is public, well documented, and almost never in the patient's hands. It lives in clinical guidance, not on the phone of the person actually doing the recovering.
What it does
Rebound is a recovery companion for people recovering from concussion. The daily loop takes about a minute:
- Log an activity — a walk, a half day at work, ten minutes of jogging
- Rate six symptoms before it — headache, dizziness, nausea, light sensitivity, fatigue, brain fog, on a 0–10 scale with plain anchors
- Rate the same six after it, plus an optional note in your own words
- Watch the record build — dated, ordered, including the days you moved back a stage
- Bring it to the appointment — one copyable summary, structured for a conversation
The app follows the six-stage graduated return-to-sport strategy from the Concussion in Sport Group consensus statement (Amsterdam 2022), published for the public as the CDC HEADS UP return-to-play progression. The attribution appears in the app itself, not only in the documentation.
The interface switches between English and Indonesian — and so does the doctor summary, so someone recovering in Indonesia can hand an Indonesian clinician an Indonesian record.
The decision that shaped everything
The obvious product here is an app that tells you when you're ready for the next stage. That app would be easier to build and far more dangerous.
Rebound's starting point is the opposite:
Rebound records your progress. It does not determine when you should progress.
Every other decision follows from that sentence. The app knows the framework, tracks the logs, and computes symptom differences — then stops, deliberately, at the line where a clinical judgment would begin.
How I built it
React 19, Vite, hand written CSS, and browser localStorage. No UI framework, no state library, no backend, no dependencies beyond React and Vite.
The architecture is deliberately narrow, and the safety boundary lives in the code rather than in disclaimer text:
There is no canAdvance(). No isSafe(), no shouldStop(), no isCleared(). Those functions do not exist in the source. recovery.js exposes calculateSymptomChanges() and hoursSinceLastStageChange() — functions that return facts, never permission. Stage changes happen because a person chose to record one.
The +2 threshold is never wired to the UI. Published guidance describes mild, brief symptom exacerbation as potentially tolerable within stated limits. That number lives in stages.js as GUIDANCE_NOTE_THRESHOLD and is imported by no logic module at all. It exists to be read, not to evaluate anyone. The moment a threshold controls a button, the app has quietly become a decision engine.
The 24 hour interval is context, not a gate. The app reports elapsed hours beside what the guidance says. It disables nothing.
There is no field called worsened. Naming a number "worsened" is already a clinical read. Rebound stores per-symptom deltas reported as-is. Dizziness 1 → 7 (+6) appears exactly that way, with no adjective attached.
Moving backwards has equal weight. Guidance describes returning to an earlier step when symptoms return. An app that only moves forward implies that moving back is failure.
No database, no account, no server. Recovery logs stay on the device.
Challenges I ran into
The hardest problem was language, not code. Early drafts of the progression screen had a status badge reading "Ready to advance". I changed it to "Looks good to discuss", then "Ready for review". Each euphemism was still the app issuing a verdict. The fix was structural rather than lexical: remove the badge entirely and show the observation. Last log · Stage 2 · 15 min walking · Headache +1. The person draws the conclusion.
Choosing a symptom scale required real research. Two different scales exist in this field for two different jobs. Symptom inventories such as SCAT rate symptoms 0–6 to produce a total severity score. Exertion-related exacerbation — whether an activity made things worse, which is exactly what Rebound records — is described on a 0–10 scale, and that is the scale the Amsterdam guidance uses when describing a tolerable increase as no more than two points. Rebound measures the second thing, so it uses 0–10.
It also deliberately does not reproduce SCAT6, which may be copied freely in its original form but requires written permission from BMJ for digital reformatting. Rebound is a digital reformatting by definition, so it uses its own symptom set with generic anchors rather than reproducing a licensed instrument.
Subjective numbers needed a footing. "Rate your headache 0 to 10" is nearly meaningless without anchors. I defined them by function rather than sensation: mild means you notice it but carry on, moderate means it interferes with what you're doing, severe means you have to stop. The guidance in the app also says the important part out loud — use the same judgement each time, because what carries meaning is the change from before to after, not the absolute number.
Value arrives late. A tool whose worth appears only after a week of use is hard to demonstrate in four minutes. The answer was a labelled sample recovery: eight days of fictional data, one setback, one step backwards, loadable in one tap and never written to storage, so exploring it cannot overwrite a real record.
Accomplishments that I'm proud of
The safety boundary is verifiable, not claimed. Anyone can search the source and confirm those functions are absent. That is a stronger statement than any disclaimer.
The interface is shaped by the condition. Concussion recovery involves fatigue, brain fog, and light sensitivity, so guidance is a permanent part of the screen rather than a dismissible popup, colours are warm and muted rather than clinical white and pure black, dark mode follows the system preference, prefers-reduced-motion is respected, and there is no animation anywhere in the app.
The empty state teaches instead of apologising. A first-time user does not see "nothing logged yet". They see the three step loop, ending with the part that matters most for a tool like this: come back tomorrow.
It handles the unhappy path. Symptoms returning and a stage being repeated is the normal shape of recovery, not an edge case, and the record shows it plainly.
What I learned
Restraint is a feature. Most of the work on this project was deciding what the app must refuse to do, and then defending that decision against every reasonable-sounding suggestion to soften it. A status badge, an auto-advance, a threshold that greys out a button — each would have made the app feel more helpful and made it quietly unsafe.
I also learned that translation is a safety surface. When adding Indonesian, the sentence "Rebound records your progress, it does not determine when you should progress" had to survive intact. A loose translation turning records into determines would undo the entire product in one line.
And deploying on day one meant there was always something real to submit.
What's next for Rebound
- Export the record as a file, not only as copyable text
- Wider language coverage beyond English and Indonesian
- A printable one page version for clinics that still work on paper
- Validation work with clinicians, which is the only path from prototype to something anyone should rely on
Built With
- css
- javascript
- localstorage
- react
- vercel
- vite