PainSense · Private beta

A pain tracker for people who open it while they hurt.

A calm pain journal for people with chronic or recurring pain: one number is a complete log, each pain keeps its own history, and the record becomes a one-page report for the next appointment. iPhone, Android and the web from one codebase, in private beta.

Studio2026–presentFounder · Product designer · Design engineer

I designed and built the whole product: the product definition, the design system and its Figma library, the app on three platforms, the backend, billing, the store listings and the marketing site.

PainSense · Studio

What shipped: an app for iPhone, Android and the web from one Expo codebase, a design system with a guardrail in CI, a Figma library that mirrors it, a backend on Firebase, web and in-app billing, store listings for both stores, and a marketing site.

  • In private beta. The app runs on Google Play internal testing and TestFlight, and payments are in test mode. The stores wait until people with chronic pain have used it for two weeks; the beta sign-up is open.
  • 42 product stories with IDs, each tied to a test, so every platform and every test round checks against the same definition.
  • Not a medical device. It doesn't diagnose or treat anything. It keeps a record.

The screens on this page show demo data: Alex and Sam are not real people.

Forty-five seconds on the product, from its website: log just the intensity, add the details later, say it when typing is too much, see each issue's own trend and what sets it off, and bring the whole story to the appointment. Demo data. With sound.

The problem

Pain diaries get abandoned because logging takes effort at exactly the moment the person has none. Then the doctor gets a vague memory, "it's been bad lately", instead of a history.

Every decision below starts from one premise: people open this app while they hurt. Every screen has one obvious action, nothing is bright or sharp, and the touch targets are big enough for an unsteady thumb.

Six screens of the running app with demo data: logging a flare-up with an intensity of 7, marking a knee on the body list, the home screen with separate pain issues, insights with a 30-day trend and common triggers, a one-page pain report, and the home screen in Night mode
The running app, from the store screenshots: log in seconds, mark where it hurts, keep each pain separate, see patterns, bring a summary, and Night mode for the hardest days.

Product decisions

One number is a complete log

On a bad day the only thing worth asking for is the intensity. Step one of the log is a single slider with a Save now button, and that alone is a complete episode. Where it hurt, the type of pain, triggers, what helped, how long it lasted, a voice or video note: all of it is optional and can be added later, when the person feels up to it. The copy says so on the screen: just the intensity is enough for now.

Each pain keeps its own story

Most people with chronic pain have more than one problem: migraines, a lower back, a left knee. Episodes are grouped into pain issues, each set up once with its own history and its own seven-day trend on the home screen. The doctor sees the migraines as migraines, not as noise around the knee.

One task at a time

Testing on a real iPhone showed that Save stayed tappable in the middle of a recording. That became a design rule, written into the design system: while the app is doing something, everything that would interrupt it waits. An audit against the rule found fourteen more places that broke it, and all of them were fixed in the same release.

Don't fake features the product doesn't have

The design concepts included a weather alert ("pressure is dropping"), medication reminders, caregiver sharing and a daily check-in. None of them are in the product, on purpose. They stay out until the core loop of logging and reviewing is proven with real people, and the marketing makes no promise the app can't keep.

Privacy is part of the product

Health data needs more than a privacy policy. Usage analytics are off everywhere, so nothing about what someone does in a health app leaves their device. A one-time consent screen comes before the first log. Episodes logged with no signal are queued on the phone and sync later, even if the app is closed. Voice and video notes play through links that expire after fifteen minutes, and deleting the account removes everything, payment records included.

A price set for conversion, not cost

Running costs are about $27 to $47 a month, and per-person costs are cents. Pro costs $4.99 a month or $34.99 a year, lowered from $9.99 and $79.99 once a written cost model showed that the old price only made sense for a product with reviews it doesn't have yet. Free covers unlimited logging, issues, the body map, the last thirty days and Night mode. Pro adds full history, 90-day trends, the PDF report, and voice and video notes, with video capped at a minute so storage stays the only cost that grows, and stays small.

Design system

The PainSense design system cover in Figma: Calm by design, for people who open the app while they hurt. 141 colour variables, 2 themes, 11 pain-severity steps, 24 text styles, 39 spacing, radius and size values, and a strip of eleven severity colours from green to coral
The design system's cover. Calm by design: one obvious action per screen, nothing bright or sharp.

The design system is code first. The tokens live in the app's repository, every screen is built from them, and a check in CI fails a pull request that reaches for a raw value, which is how the app reached zero design debt and stays there.

Two themes carry it. Slate is the everyday dark theme; Night is darker still, for a dark room and a headache. Pain severity has its own eleven-step scale, 0 to 10, from green through amber to a soft coral, so the same number always looks the same wherever it appears: the slider, an episode row, the trend chart, the report.

Four severity meters in Figma: intensity 2 of 10 labelled Mild, 5 Moderate, 7 Severe and 9 Extreme, each with a gradient bar from mild to extremeThe severity meter at four values. One component, one variant per band, the colour from the severity scale.

In Figma

Designers work in Figma, so the system is mirrored there too. Code stays the source of truth; the Figma library follows it, built from the same token file.

  • Foundations: 141 colour variables with Slate and Night as modes, 39 spacing, radius and size variables, 24 Inter text styles and 4 shadows.
  • Components, only what the screens need: 48 icons from the app's own icon font, then 27 components, from Button, Chip and Switch to the PainSlider, the SeverityMeter, EpisodeRow, IssueCard and the TrendChart.
  • Product screens: 13 iPhone screens in a second file, every one built from live instances of the published library, with nothing detached.
The log flow in Figma: step 1, intensity 7, Severe, with the vertical slider; step 3, impact and relief, with Had to lie down checked and Dark room, Rest and Medication selected; Episode saved, with the trend it was added to; and the episode itself, intensity 5 of 10, Moderate, throbbing pressure in the head, triggers poor sleep and screen time
The log flow: intensity, impact and relief, saved, and the episode as it reads afterwards. Steps two and three are optional.

The product file is wired into a prototype with two flows, first run and daily use: the onboarding, the tab bar, the whole log flow, an episode, and a Night mode toggle.

Home in Figma twice, the same frame in the Slate theme and in the Night themeHome in Slate and in Night: the same frame, only the variable mode changed. The weather and medication cards are design concepts the product deliberately does not ship.

The prototype is clickable here: click through the prototype →. The library is open to look through: open the design system in Figma →

How it's built

  • One codebase, three platforms: Expo and React Native for iPhone, Android and the web, with native Google sign-in and Sign in with Apple.
  • Backend: Firebase Auth, Firestore, Storage and nine Cloud Functions, with security rules that validate episodes, issues and profiles.
  • Billing: Stripe on the web and RevenueCat in the apps, behind one entitlement computed on the server, so the app and the storage rules can never disagree about who has Pro.
  • Releases: every change is a pull request with tests; semantic-release cuts the version; previews run against a separate staging project so they never touch real data; JavaScript fixes reach testers over the air, and store builds are only for native changes.
  • Marketing site: a separate Astro site on Vercel that shares the app's colour tokens and plan file. The first version was built in Expo and looked like it; React Native views make poor web pages.

Where it stands

PainSense is built and running, and it is not in the stores yet. Both store builds are on invite-only test tracks, payments are in test mode, and the listings are saved as drafts.

That is deliberate. The positioning and the personas are drafts until people with chronic pain have used the app, so the next step is a two-week trial with five of them. The question the trial has to answer is the one the whole product rests on: whether logging really takes seconds on a bad day, and whether the summary is something a doctor will read.

If you live with recurring pain and would like to help answer it, the sign-up takes a minute: join the beta →

Click through the prototype → · Open the design system in Figma →

Product designDesign systemsMobileHealthFigmaReact Native

This is the ownership I bring to a team.

Hiring for a senior or staff role where design, code, and AI meet? Let's talk.

Or send a note. Project work for a season, also by note.