← Back to list

6 Years, Counted by a Text File: Milestones Without an App

Every habit and streak app wants an account, a subscription, and a daily tap to keep your streak. I replaced all of them with one line of…

Max Holovanov · 2026-05-31 18:03 · 66 claps · 4.3 min read
#productivity #self-improvement #habits #minimalism #emacs
Open on Medium ↗
Wiki topics: PSY · Psychology 🚀 · Self Improvement ⏱️ · Productivity 🏠 · Home & Living

6 Years, Counted by a Text File: Milestones Without an App

Every habit and streak app wants an account, a subscription, and a daily tap to keep your streak. I replaced all of them with one line of plain text and a date. It has counted 2,296 days and never once asked me to check in.

The thing streak apps get wrong

Open any habit or streak tracker and the deal is the same: make an account, maybe pay monthly, and — this is the part that grates — tap every day to keep the streak alive. Miss a day and the app scolds you, resets the number, guilts you with a notification. The streak isn’t really tracking your life; it’s tracking your engagement with the app.

That’s backwards. The fact that I stopped drinking on a particular morning in 2020 is true whether or not I open an app today. The date happened. It doesn’t need maintaining. It needs remembering — and a little arithmetic.

So I stopped tapping. I write the start date down once, in plain text, and let the computer do the counting forever.

One line and a date

A milestone, in my system, is an org-mode heading with a single property — the day it started:

That’s the whole record. A title, a tag to group it, and :STARTED:. I never touch it again.

Capturing one takes a few seconds — a capture template prompts for the date and writes the skeleton for me:

Change default capture logic in emacs

Change default capture logic in emacs

Capture [m]

Capture [m]

Hit the capture key, type the title, pick the date, done. No “log today” button, because there is no today to log — the only fact that matters is the start.

Where it comes alive: the timeline view

A start date on its own is just a fact in a file. The magic is a small agenda view that reads every milestone and turns each date into a living period — years, months, days, and the running total since:

Before click [m]

Before click [m]

Agenda [m]

Agenda [m]

Every time I open it, the numbers have advanced on their own. Nothing was tapped, nothing was confirmed. The view simply does today − started for each line and prints the elapsed time. The phrasing matters to me: not streak: 2296 — a cold score that implies fragility — but 6 years, 3 months, 15 days, a span of life that’s simply accumulating.

And it’s not only for quitting things. I track arrivals too — the day cycling entered my life, the day I started swimming, the day a tool I love showed up. Same mechanic, opposite sign: instead of how long since I stopped, it’s how long I’ve been doing this. A milestone is just a date that means something, and the view treats them all alike.

A milestone can carry more than a date

The heading is the minimum, not the maximum. Because it’s just org, a milestone’s body can hold anything — a note on why it mattered, a link, a photo. One of my older ones is the day I pulled every label off my keyboard and forced myself to touch-type blind (Dvorak, blank keycaps, no glancing down). I dropped a picture of the bare keys right under the heading:

In the timeline it stays a tidy one-liner with the running count — 2y 8m 14d and climbing. Press RET on that line and the note opens with the photo inline. The counter stays clean; the context (and the image) is one keystroke away — and the picture is just a file sitting next to the text, not locked inside an app’s database.

Why plain text wins here, specifically

I’ve written before about **I Spent 9 Years in OmniFocus. Then I Switched to a Text File. Milestones are the purest example of why it’s worth it:**

  • No subscription, no account. It’s a file. There is nothing to pay for and no vendor who can sunset the app and take my dates with it.
  • Completely private. My sobriety date, the things I’ve quit, the things I’ve started — none of it is on someone’s server being mined. It lives in a file I sync myself.
  • No daily ritual, no guilt. A streak app breaks if you forget to open it. A date can’t be broken by forgetting — it already happened. Set it and walk away.
  • It outlives every app. These records are years long. The only format I trust to still be readable in another decade is plain text. An app’s database isn’t a promise; a .org file is.
  • It’s mine to shape. Want to group milestones by tag, sort them, show only the big ones, change streak to years, months, days? It’s a few lines of config, not a feature request to a company.

The whole point in one sentence

A milestone tracker shouldn’t be a thing you use. It should be a thing you set once and forget, that quietly keeps counting while you get on with living. A date in a text file does exactly that — for free, in private, forever.

The capture template and the timeline view both live in my dotfiles — [https://github.com/maxclax/dotfiles]. Take what’s useful, and go write down a date that matters.


메타데이터
post_id
e3e54723f9bc
slug
6-years-counted-by-a-text-file-milestones-without-an-app-e3e54723f9bc
url
https://medium.com/@maxclax/6-years-counted-by-a-text-file-milestones-without-an-app-e3e54723f9bc
canonical_url
https://medium.com/@maxclax/6-years-counted-by-a-text-file-milestones-without-an-app-e3e54723f9bc
author_url
https://medium.com/@maxclax
status
ok
fetched_at
2026-06-15 20:49:13