Inspiration
In June 2026 I made PomoSauna as a single web page: a monk meditating through twenty-five minutes of sauna heat, then cooling beneath a waterfall, drawn on a canvas with synthesized sound (pomosauna-web). I kept it open in a tab while I worked, and it did something no focus app had done for me: it was pleasant to look at, and it asked for nothing.
It also had the web's limits. Lock the phone and the timer stops mattering; the bell never rings. PomoSauna for iPhone is that page rebuilt as a native app, so the scene can keep time while you look away.
What it does
A monk sits in a sauna. You start a session, the room fills with steam, and a ring holds the time. When the phase ends, a bell opens the waterfall and the monk cools beneath it. Then the heat again. That is the whole app.
- Pomodoro: focus and rest alternate on their own, with a cue at each change. Twenty-five and five to begin with; any lengths you like.
- Relaxation: one continuous session with ambient sound. No countdown, no cue, nothing to finish.
- It keeps time while you look away: a Live Activity on the Lock Screen and in the Dynamic Island counts down without the app running, and the cue still sounds at every phase change with the phone face down.
- Sound you choose: a looping ambient bed and a phase-change cue, picked separately, each auditionable before you decide.
And what it does not do, on purpose: no account, no streaks, no statistics, no badges, no reminders to come back, no ads. The app has no opinion about the days you skip.
How I built it
- Swift 6, SwiftUI over SpriteKit. The scene (monk, stove, steam, waterfall) is a SpriteKit scene with particle emitters; the HUD is SwiftUI composited on top. The monk is a port of the web version's canvas drawing, and the background stops and particle numbers are lifted from its render loop, so the two versions look like one product.
- The timer is an end-time state machine, not a ticking countdown. iOS suspends the app, so the view model stores when the phase ends and derives everything else. Phase-change cues are pre-scheduled as local notifications so they fire while suspended; a session is persisted on backgrounding and restored at launch, and boundaries that passed while the app was terminated roll forward silently instead of replaying sound.
- ActivityKit for the Live Activity, using the system's auto-updating countdown so it stays accurate with the app not running.
- AVAudioEngine with separate ambient and cue channels, looping beds and a background audio session.
- RevenueCat behind a single protocol: view models never see an SDK type. One
premiumentitlement is sold three ways (monthly, yearly, lifetime), and the introductory trial shown on the paywall is read per user, because Apple grants it once per subscription group. - 260 unit tests with an injected clock advanced by hand, so the timer is tested without sleeping. Every bug fix starts with a test that reproduces it. Built with Claude Code as a pair programmer, working from a written spec.
Challenges
- Time without a running app. A countdown that ticks is wrong the moment iOS suspends it. Moving to end dates fixed the display, but sound was harder: the cue has to be a notification scheduled in advance, and the app must not play it a second time when it wakes up.
- Calm and accessible at once. Thin type on a saturated gradient is the look, and it fights contrast and Dynamic Type. An accessibility pass lightened the brand blue wherever it is text, let the phase label grow past twice its size, and closed VoiceOver and Voice Control gaps. The particle scene dampens for Reduce Motion and Low Power Mode instead of switching off.
- One sound at a phase change. The in-app cue and the scheduled notification could both fire; the app's own cue now has to be the only sound you hear.
What I learned
The features I cut protect the product more than the ones I built. Statistics were the obvious thing to add, and they are where every focus app starts grading you. Leaving them out is what keeps PomoSauna something you are glad to have on the table.
What's next
Listening to the first users. The Live Activity already reaches the Apple Watch Smart Stack; if people ask for more on the wrist, a silent haptic cue at each phase change is the next step, never a port of the scene.
Monetization
The free app is complete: both modes, the whole scene, the Live Activity, the default sounds. PomoSauna Premium unlocks unlimited presets, all six clock colours, the full sound library, every curated background and your own photos. Monthly or yearly with a free trial, or one payment forever: the subscription exists so people can try Premium before paying, and Lifetime is there for people who would rather not subscribe. Locked sounds and colours can be previewed before purchase. No ads, ever.
Built With
- activitykit
- avfoundation
- claude-code
- ios
- revenuecat
- sprite-kit
- storekit
- swift
- swiftui
- widgetkit
- xcode
Log in or sign up for Devpost to join the conversation.