This is Part 1 of a two-part series on building Habit Arc, a local-first Android habit tracker. This part is the why and the science. Part 2 opens the hood on the architecture.
When I sat down to build this thing, I wanted to measure something real in code — not fake it with a counter.
That distinction turns out to matter more than it sounds. A streak counter is the easiest number in the world to ship: count++ on a good day, count = 0 on a bad one. It compiles, it demos well, it means almost nothing. I didn't want the number that's trivial to store. I wanted the number that's actually load-bearing for whether a habit sticks — and then I wanted to model that honestly, tests and all.
So: two goals, and I'll own the second one plainly. The first was to build a habit tracker grounded in what researchers actually know about how a habit takes hold. The second was purely selfish — I wanted to learn to build a real Android app. Not another to-do list copied out of a tutorial, but something I'd open every morning and have to live with every bug of. A habit tracker was the right size for that: small enough to finish alone, deep enough to teach me Kotlin and Jetpack Compose end to end.
This post is about the idea. If you just want the engineering, skip to the teaser at the bottom and come back for Part 2.
Streaks are a slot machine wearing a lab coat
Open almost any habit app and you meet the same machine: a counter ticking upward, a badge, a fistful of confetti for showing up. It's a slot machine dressed up as self-improvement — the exact trick games use to keep you pulling the lever. And like any slot machine, it pays out right until the day it doesn't. Miss once, the number drops to zero, and the whole spell breaks.
Here's the part that bugs me as a builder. A streak feels like motivation, but it's really a fragile reward stapled onto a real habit. The habit loop — cue → routine → reward, until the loop runs itself — is the thing that's actually doing the work. The streak counter just volunteers to be the reward slot. And it's a reward you can only ever lose. It creeps up one point at a time, quiet as dust, then goes off like a firecracker the first day you fall short.
Life is not a tidy row of perfect days. You get sick, you travel, you have the kind of week that would make a saint miss a workout. When one ordinary human interruption wipes out months of effort, a single miss stops being a stumble and becomes a verdict: I already blew it. That verdict is what kills the habit — not the day you missed, but the tailspin that follows it.
Most habit apps punish you for being human. I wanted one that expected it.
The 21-day thing is a fairy tale
"21 days to form a habit" is folklore. The number was lifted from a 1960s book by a plastic surgeon who noticed patients took about three weeks to get used to a new face — and somehow that became gospel for behavior change.
The study to actually quote is Lally et al. (2010) out of UCL, "How are habits formed?". The average time to automaticity was 66 days — roughly 3x the myth — with a range from about 18 days to more than 250, depending on the person and the habit. Later work (Singh et al., 2024) says it louder: formation times scatter so widely that any single universal number is useless.
Which means a one-size streak counter isn't just harsh — it's measuring the wrong thing. A 30-day streak on "drink a glass of water" and a 30-day streak on "write for an hour" are not the same feat, and no honest system should pretend they are.
The better question: not "how many days," but "how automatic?"
The literature already has the instrument I wanted: the SRBAI, the Self-Report Behavioural Automaticity Index (Gardner et al., 2012). Once a week, Habit Arc asks one thing:
"This habit felt automatic." (1 = not at all … 5 = completely automatic)
One number that measures the thing you actually came for — not "did you comply today" but "is this becoming who you are" — and it bends to your timeline instead of forcing you onto a calendar.
Habit Arc walks a habit through three phases — Formation → Building → Established — instead of tallying days. A habit graduates when you report it runs on its own. If two weeks say it's slipping, it quietly slips back a phase. The day count is an input. Automaticity is the verdict.
A streak measures your obedience. Automaticity is the only part that outlives your motivation.
What that changes about the app
Once you accept that framing, a bunch of product decisions stop being opinions and start being consequences:
Never miss twice. One miss is nothing; what wrecks a habit is the second miss and the "I already blew it" voice. When you slip, the app points you at the very next rep — land it and you earn back part of what the miss cost. The screen never flashes "streak lost." It says: a miss is feedback, not failure. Get back to the next rep.
A miss is yours to declare — the app never declares it for you. No automatic decay, no auto-generated "Missed." Skip a day and touch nothing, and the day stays blank. An app that assumes the worst of your silence is teaching you to dread opening it.
Growth you can watch, not a number that detonates. Each habit grows through stages — 🌱 Seedling, Sprouting, Growing, 🌲 Established, 🌳 Deep Rooted — under a 0–100 Growth Score that folds together repetition, consistency, recovery, and automaticity. Miss a day and growth slows; it doesn't torch the garden.
Building a habit and breaking one are different jobs. Before a Reduce habit even appears, setup asks for two things: the early-warning sign ("when do I feel the pull?") and the replacement ("what do I do instead?"). "Just stop" has never been a plan.
It helps you set the trigger, not just the goal. When you make a habit, it walks you through an implementation intention — the "When I __, I will __" format Gollwitzer's research found sharply raises follow-through. A goal is a wish. An implementation intention is a wish with a doorbell.
It knows some days are heavier than others. A quick daily check-in asks about stress, energy, sleep. On rough days it asks for less — a smaller, slower, easier next rep. Showing up small on a bad day is the whole trick to getting a habit through the bad day alive.
Everything stays on your phone. No account, no cloud, no analytics. Habits, journal notes, and check-ins live on your device and nowhere else — made impossible to break at the architecture level (that's Part 2).
Coming in Part 2: the engineering
The fun part, for this audience, is that none of the above is hand-wavy product copy — it's a plain Kotlin engine. Phases, the Growth Score, recovery math, the automaticity roll-up: all pure functions with no Android framework in sight, which means the whole behavioral model unit-tests in milliseconds with zero emulator. That's the payoff of not faking the number — an honest model is a testable model.
And the "everything stays on your phone" promise isn't a privacy policy, it's a build constraint. There's no networking layer in the app at all. It couldn't phone home if it tried. Part 2 gets into how I structured it that way on purpose, why the science-as-code decision made testing almost free, and the things I got wrong before I got them right.
Part 2 (architecture) is coming here: https://yannickjourney.com/blog/habit-arc-testable-kotlin-architecture
Where it is now
Native Android, Kotlin + Jetpack Compose, free, local-first. It's in a closed beta on Google Play right now with a small group living in it day to day.
I'm not really here to farm testers — I'm here to argue that consistency should survive a missed day, and to see if that lands with people who build things. But if the idea resonates and you want to actually kick the tires, the app lives here: https://yannickjourney.com/habit-arc/ — the beta's open if "a miss is feedback, not failure" sounds like the tracker you've been waiting for.



Top comments (0)