Habit trackers are the perfect small project. The data model is trivial, the interface is one screen, and because you use it yourself every day, you find out immediately what's wrong with it.

1. The data is simpler than you think

A habit has a name. A completion is a habit and a date. That's the whole model. Resist adding times, durations, notes and categories — they turn a two-second daily action into a form, and forms don't get filled in every day.

2. One screen, one tap

tracker-build.txt
Build a habit tracker. Local-first, no account, one HTML file plus
scripts. Storage in localStorage, wrapped in try/catch throughout.

The main screen: today's habits, each a large tap target that toggles
done. Nothing else above the fold.

Below: a grid of the last <n> weeks per habit, one square per day,
showing the pattern at a glance.

Also: add and delete a habit, current streak per habit, and export
everything as JSON.

Works down to 320px. Big tap targets — this is used on a phone, in a
hurry, one-handed.

3. Get "today" right

Sounds trivial, isn't. "Today" is the user's local day, not UTC. Someone ticking a habit at 23:50 and someone at 00:10 are on different days, and your storage must agree with their calendar rather than with your server.

Store dates as plain YYYY-MM-DD strings in local time. Do not store timestamps and derive the date later — that's the bug that makes days shift for anyone not in your timezone.

4. Streaks, defined deliberately

Decide what breaks a streak before you code it. Does a missed day reset to zero? Is there a grace day? Do weekends count? There's no correct answer, but there is a correct process, which is deciding rather than discovering.

5. Use it for two weeks before adding anything

You'll find one or two things that genuinely annoy you and a dozen features you thought you wanted and don't. That's the actual value of building your own tools.

Make the undo obvious. Mis-tapping a habit and being unable to untick it is the fastest way to stop trusting your own data.