Skip to content
← Studio Dailies

I didn't pay for a sleep app. I built one.

Rise wanted a subscription and my health data. My Apple Watch already had the data, so I built it.

I have a complex relationship with sleep, I can sleep anywhere, anytime so far, but when it comes to going to bed on time, its hard. I love the peace of the night for the best work but I know its never been healthy and I have tried to change this habit for years now.

After trying a few, I was about to pay for a sleep app. Rise promises to tell you when your energy peaks, when it dips & how much sleep you owe. It wants a subscription and access to your health data.

Underneath, it runs two calculations. Sleep debt is the gap between what you need and what you got, summed over the last fourteen nights. Your energy curve is predicted from the midpoint of your sleep. The rest is notifications.

My Apple Watch already had the data. So I built it.

Test before you build

Before writing any code I wanted to know whether the model predicts my days. If it said I would slump at 3pm and my 3pm felt fine, the app would be a pretty toy.

The cheapest test was typing. I opened Health and wrote down fourteen nights of sleep & wake times by hand. Two numbers a night. Nothing left my phone.

What came back:

  • Average sleep: 6h 20m
  • Sleep debt: roughly 23 hours against an eight hour need. Three full nights owed.
  • Wake time: 6:42am on average, every single morning between 5:25 & 7:50
  • Bedtime: anywhere from 10:46pm to 1:52am

That last pair changed the question. My mornings were consistent. My nights were not.

I didn't need to become a morning person. I already was one, running on 23 hours of debt. Bedtime was the only broken variable and the only one I control.

Then the check. The model named my two worst days and my two best. It predicted a slump around 3:30pm. All of it matched. Only then did I start building.

Apple shortcuts
Apple shortcuts

Getting the data out, privately

Apple Health's native export is a huge XML archive. Third-party exporters want your data and a subscription. Neither worked for me.

Apple Shortcuts can read HealthKit on the device. Find sleep samples from the last fourteen days, loop over them, format each as start, end & stage, join them, copy to clipboard. Five actions.

It took most of an evening. Here is what broke:

  • The variable picker defaulted to Current Date. Every line was the time I ran it.
  • The filter said Any instead of All. It tried to return every health sample I own.
  • Two actions sat inside the loop instead of after it.
  • iOS refused outright, trying to share 337 Health items. There is a setting for that under Shortcuts, Advanced.
  • The final join grabbed the last line only. One segment instead of three hundred.

Each fix was one tap. Finding each one was not. That is the real cost of doing this yourself.

App home page
Home Dashboard

The app

One HTML file. No framework, no server, no account. Your data lives in your browser.

It opens on a score out of 100 tied to your debt, with the line that matters underneath: under five hours of debt is where it stops biting.

Below that, the day. Your predicted energy curve against a dotted line showing the same day fully rested. The gap between them is what sleep debt costs you, drawn. Peak & dip are shaded. A gold line marks now.

Under the curve sits a lane of habit windows. Rise runs more than twenty timed nudges. I kept seven: morning light, last caffeine, a nap window, time to train, last alcohol, last meal, screens down.

Every time is derived from your own wake time and target bedtime, so they move as you do. The nap window only appears when debt is over five hours. Catch up and it disappears.

Tonight's target is thirty minutes earlier than your usual. Not ten o'clock. A target you miss on night one teaches you to ignore the app.

First night

I fell asleep at 11:04pm. Over an hour earlier than usual and ahead of target.

I still only got 6h 31m. The app showed 74 minutes awake in the middle of the night and my efficiency dropped to 84%.

My kid woke up. I was up helping them back to sleep.

One week later

The debt number moved slowly. 23 hours down to 21. Two hours repaid in a week is not a transformation.

Bedtime moved faster. My median was 12:22am when I started. Last four nights: 11:04pm, 1:03am, 11:30pm, 10:31pm.

Sunday night I slept 8h 02m. Best night in the entire record.

The debt is the lagging number. Bedtime is the leading one. I would not have known which to watch without building the thing.

Start screen for the sleep dept app
Start screen for the sleep dept app

It's yours if you want it

It's free and open source. There's a See it with sample data button, so you get the whole thing, score, curve, dip and habit windows, without setting anything up first.

https://shafakat.studio/sleepdebt

One HTML file. No account, no server, no analytics. Everything is computed in your browser and nothing is uploaded, which you can check, because the source is right there.

The Shortcut is still the hard part. The five actions are in the readme.

What's next

My own copy is heading somewhere else. Right now it forgets everything older than fourteen nights. Next it keeps everything, learns my actual sleep need & starts predicting tomorrow as well as today.

The data was already on my wrist. It needed a question.

No sleep app knows the difference between a body that can't hold sleep and a parent getting up. So I added a tap. Mark a night as woken externally and the long awake blocks leave the efficiency figure. The lost sleep still counts toward debt, because it was still lost. The system stops recording it as a failure.