TAKT

My first mobile app — feel your pulse, tap the screen, know your heart rate


Why I built it

Sometimes my heart just starts racing, and I never had a good way to actually check what it was doing. I don’t own a smartwatch, and reaching for one every time isn’t realistic anyway. But I always have my phone. So I built TAKT: you find your pulse the old-fashioned way, with two fingers on your wrist or neck, then tap the screen in time with each beat, and the app works out your heart rate from the rhythm of your taps.

It’s my first ever mobile app, and it’s still very much a work in progress, but there’s already a lot in it I’m proud of.

The name fits, too: Takt is the German word for beat, rhythm, or measure. For an app that’s all about the rhythm of your heart, and tapping in time with it, it was too perfect to pass up.

Getting to the right tools was half the battle

Before writing anything, I did a good bit of research into how to even build a phone app. My first stop was Android Studio, which was, honestly, a headache, heavy, slow to set up, and a lot of ceremony just to get “hello world” on a screen. I didn’t want to fight my tools before I’d even started building.

Then I found Expo Go (which runs on React Native), and it genuinely changed the game for me. I write the app in JavaScript, and it shows up live on my actual phone, updating the instant I save a file. No painful build cycle, no emulator wrestling. For a first-timer it was the difference between giving up and actually enjoying the process. Expo is awesome, and I’m not going back.

The clever bit: turning taps into a heart rate

The hard part of a tap-to-measure app is that humans are bad clocks. Your taps are never perfectly even, you’ll miss a beat, double-tap, or drift. If I just averaged the gaps between taps, one fumble would wreck the reading. So the BPM calculator does real signal cleanup:

  • Skipped-beat detection. If a gap between two taps is roughly double the average, you probably missed a beat, so it splits that gap into two. Roughly triple? It fills in the missing beats proportionally.
  • Outlier removal. It then throws out the genuinely bad gaps using the IQR method (the same interquartile-range trick used in statistics to spot outliers), so a single wild tap can’t drag the result around.
  • Only then does it average what’s left and convert to beats per minute.
// if a gap is ~2x the average, a beat was skipped — split it
if (interval > avg * 1.7 && interval < avg * 2.3) {
  corrected.push(interval / 2, interval / 2);
}
// then drop outliers with the IQR fence before averaging
const filtered = corrected.filter(i => i >= q1 - 1.5*iqr && i <= q3 + 1.5*iqr);

The screen shows your BPM updating live as you tap, and two seconds after you stop, it locks in the final number and saves it. There’s no “start” or “stop” button anywhere — the app works out that you’re done by noticing you stopped:

const handleTap = () => {
  const newTaps = [...taps, Date.now()];
  setTaps(newTaps);
  setCurrentBPM(calculateBPM(newTaps));   // live number, every tap

  clearTimeout(timeoutRef.current);
  if (newTaps.length >= 2) {
    // no "stop" button — 2s of silence means you're finished
    timeoutRef.current = setTimeout(async () => {
      setFinalBPM(bpm);
      setIsComplete(true);
      if (autoSaveEnabled) await saveReading(bpm);
    }, 2000);
  }
};

Every tap resets that timer, so the app just quietly waits you out. That forgiveness is what makes it usable instead of a frustrating rhythm test.

The feature I like most: Stress Relief

Because the whole reason I built this was a racing heart, I added a mode that does something about it, not just measures it. The Breathe / Stress Relief flow is three steps: measure your heart rate, follow a guided breathing session, then measure again and see the difference.

The breathing itself is the nice touch. A circle expands as you breathe in and shrinks as you breathe out, and the pace adapts: it starts at a 4-second cycle and gradually stretches toward 6 seconds as the session goes on, easing you into slower, deeper breaths without you ever noticing it happen.

That’s just a linear interpolation against how far through the session you are:

const runCycle = (elapsed) => {
  const progress = Math.min(elapsed / duration, 1);
  const startDuration  = 4000;   // 4s cycle at the start
  const targetDuration = 6000;   // easing toward 6s by the end
  const cycleDuration  = startDuration + (targetDuration - startDuration) * progress;
  const halfCycle = cycleDuration / 2;   // half in, half out

  Animated.timing(breatheScale, { toValue: 1.6, duration: halfCycle, ... })
  // ...then exhale back to 1, then schedule the next cycle
};

If I’d just told people “breathe slower,” it wouldn’t work. Hiding the slowdown inside the animation means you follow the circle and your breathing slows on its own.

At the end it shows your before and after side by side, and if you dropped 5 BPM or more you get a burst of confetti. Watching a number actually go down after breathing is weirdly satisfying, and genuinely calming.

The stuff that makes it feel like a real app

A big lesson from this project was how much work lives around the core feature. TAKT also has:

  • A proper structure — three tabs (Measure, History, Settings) with real navigation, not one screen doing everything.
  • History that persists — every reading is saved on-device with AsyncStorage, tagged Resting / Normal / Active / Elevated, with weekly stats.
  • Light and dark themes — a theme system that follows your phone or lets you force one, threaded through every screen.
  • An onboarding flow for first launch, an animated EKG background, custom hand-drawn SVG icons, tap ripples, the works.

None of those are the “point” of the app, but together they’re what separates a school project from something that feels finished.

To be clear: TAKT is a tap-based estimate for curiosity and calm, not a medical device. If your heart rate genuinely worries you, see a doctor, not my app.

Where it’s at

It’s a work in progress, there’s plenty I still want to add and polish, but it already does the thing I built it for: when my heart races, I can pull out my phone, tap along, breathe, and watch it settle. As a first mobile app it taught me a huge amount, React Native and the whole Expo workflow, component architecture, on-device storage, navigation, and how much thought “simple” apps actually take. I’ve got a lot more planned for it.

Share: LinkedIn