
I marked four days, skipped one, and marked two more. A tracker I had used before would have called the skip a reason to throw the four away. This one leaves them. The empty day is a gap. It is not a delete key.
The sample is September 2026. Water is every day. It is marked on 1 Sep, 2 Sep, 3 Sep and 4 Sep, empty on 5 Sep, then marked on 6 Sep and 7 Sep. That is six marks. On 22 Sep 2026 the current run is 0, because the days after 7 Sep are empty. The six marks are still in the month.
The page is Habit Tracker.
The fifth is a gap
I wanted a grid I could tap, and a sheet I could print, without an account. I also wanted the missed day to stay a missed day. If 5 Sep becomes unmarked by wiping 1 Sep through 4 Sep, the grid is lying about the week I already lived.
Water in the sample is the daily row. The cells for the 1st through the 4th are marked. The 5th is not. The 6th and the 7th are marked again. Count the marked days in September and you get 6. Count a "current run" on 7 Sep, the last of those marks, and you get 2: the 6th and the 7th, stopped by the empty 5th. The 1st is still marked while that run is 2. Those are different numbers on purpose.
On 22 Sep 2026, which is a Tuesday, Water's current run is 0. Today is empty, and so is every day back to the 8th. The walk stops at the first empty scheduled day. It does not walk through that gap and pretend the early September marks are the run you are on. It also does not remove them. Mark 22 Sep and the run becomes 1. The 5th is still empty. The 1st is still marked.
A day you did not mark stays empty. The days you did mark stay marked.
That line is on the page. The sample is there so you can see it without inventing a month of your own first.
What the run is counting
The current run is consecutive scheduled days that are marked. If today is on the schedule and it is marked, the run includes today and walks backward. If today is empty, or today is not a scheduled day, the walk starts at yesterday. It stops at the first scheduled day that is empty.
An empty today does not zero the history. It also does not get a free pass forever. Once the day is behind you and it was on the schedule, it is a gap. The run after the gap is a new run. The marks before the gap stay in the month count.
I am not going to call the month count a score. Six marked days is six marked days. A run of 0 on the 22nd means you have not marked the recent scheduled days. It does not mean September failed.
There is no points total, no pet, and no prize for a long run. The grid is the record. If a game is what keeps you marking, this is the wrong page. I built the boring one.
Tuesday is off
Stretch is the other sample row. Its days are Monday, Wednesday and Friday. 1 Sep 2026 is a Tuesday. I checked the weekday of that stored date, and it is Tuesday in every time zone, because the date is a calendar day and not an instant. The Tuesday cell is off. You cannot mark it. It is not a miss.
2 Sep is a Wednesday, and it is marked. 4 Sep is a Friday, and it is marked. On 4 Sep the current run is 2. The walk goes Wednesday, skips Thursday because Thursday is not on the schedule, counts Friday, then hits the previous Monday, which is 31 Aug and is not marked. The run stops. 2 Sep remains.
7 Sep is a Monday. In the sample it is not marked. On 8 Sep the current run for Stretch is 0, because that Monday is a scheduled day with no mark. 2 Sep and 4 Sep are still in the month. A skipped Monday did not delete the Wednesday.
| Date | Weekday | Water | Stretch |
|---|---|---|---|
| 1 Sep | Tuesday | marked | off |
| 4 Sep | Friday | marked | marked |
| 5 Sep | Saturday | empty | off |
| 7 Sep | Monday | marked | empty |
Saturday is off for Stretch the same way Tuesday is. Water, being daily, treats Saturday as a real day. The 5th is Water's gap. It is not Stretch's problem.
The day does not slide
A mark is stored as a date, 2026-09-21, not as a timestamp. If I stored the instant and then opened the page in another zone, the day could move.
Take 22 Sep 2026 at 03:30 UTC. In New York that is still 21 Sep. In Tokyo it is already 22 Sep. The page asks the clock in the zone you are in, and it writes that calendar day. A mark you made for 21 Sep stays 21 Sep when you open the same browser store in Tokyo. The stored string does not get reinterpreted.
The weekday of a stored date is read at noon UTC, so the machine's zone cannot bump 2026-09-01 onto Monday or Wednesday. Tuesday stays Tuesday. That matters for a habit that is only some weekdays. If the weekday slid, an off day would become a miss, or a miss would become an off day, and the grid would be wrong without you touching it.
Eight names
The page holds 8 habits. A ninth is refused, and the eight you have stay. A blank name is refused. A habit with no weekday checked is refused. The name is cut at 40 characters. I would rather stop you at the ninth row than draw a month that falls off the paper.
Remove one habit and the other stays, marks included. In the sample, removing Water leaves Stretch, and Stretch still has 2 Sep. Undo puts Water back. The undo stack keeps the last 30 grids. Delete saved habits asks a second time, because one click is how a month disappears by accident. After the second click, Undo can still put the grid back, until you have undone past it or closed the tab without a backup.
The month buttons move the view. They do not move the marks. September's six Water marks are still there when you look at August, and they are still there when you come back. The view is a window. The record is the dates.
The blank page
Download a blank month writes one PDF. The habit names are the row labels. The boxes are empty. I checked a September Letter page: one page, 612 by 792 points, the words September 2026, Water, and Stretch, and no mark drawn in a box.
Include marks on the PDF is off until you turn it on. Then the button says Download this month, and a marked day gets an x in the box. That choice stays in this browser. It is not on the share link. A shared address should not be a way to publish which days you drank water.
Letter is the default. A4 is 210 by 297 millimetres, which in the file is about 595.28 by 841.89 points. The same grid, the other paper. pdf-lib draws it. That library was already in the site, MIT licensed, and I used it rather than adding another PDF writer.
The printable calendar on this site is a different sheet. It is a month of days you write in, with optional US holidays. This one is a row per habit. If you wanted the wall month, use that page. If you wanted eight rows of boxes, use this one.
The file you move yourself
There is no account. There is no sync. I am not going to imply that the grid will be on your phone because you marked a day on your laptop. It will not.
The browser stores the grid under softery.habit-tracker.data. The knobs, the month you were viewing, the week start, the paper, and whether marks go on the PDF, sit under softery.habit-tracker.settings. Close the tab and both are still there, in this browser. Clear the site data, or use another browser, and they are gone.
Download backup writes a JSON file with version 1, the habits, and the marks. Check backup reads a paste and tells you the count, for the sample "2 habits, 8 marks", and it does not replace anything. Replace the grid is the step that overwrites. A file whose version is not 1 is refused. The grid you already have stays.
If this browser refuses to store the grid, the page says so. Download the backup before you close the tab. That is the whole recovery plan. I am not going to pretend a server has a copy.
What the link carries
Copy settings link builds an address with the month, the week start, and the paper size. For the sample that is month 2026-09, and it does not contain the word Water, and it does not contain the date 2026-09-01. I checked.
A ?v= on the end is a cache buster. It does not replace the knobs this browser stored. If you had August, Monday weeks, and A4 saved, a bare ?v= leaves them there.
Include marks on the PDF is local. Turning it on changes the download. It does not change the link. Someone opening your link gets the month and the paper. They do not get your days.
Mixpanel and Google Analytics load with Softery.io. They see that someone opened the tool and which knob moved. A size bucket and a habit count can go out with a download. The names and the dates do not. I will not tell you the whole site makes no requests. The grid does not leave with them.
A wall calendar is the other tool
If the thing you wanted was a month on the fridge, with a box under each day and the US holidays on or off, that is the Printable Calendar Generator. It is not this grid. This grid does not know Independence Day. It does not care that 4 Jul 2026 was a Saturday. Those questions belong on the calendar page.
If a backup paste looks wrong, the JSON Formatter & Validator will show you where the text broke. It does not import the habits. Import is the Replace button on this page, after Check backup has told you the count.
I am not putting a third product in the way. Two neighbors, both because of a thing this page actually hands you: a month of paper, and a JSON file.
What I left out
No points. No streak freeze that spends a coin. No reminder notification. A reminder would need permission and a server, and this page does not have a server path for your habits. If the tab is closed, nothing pings you.
No shared household grid. Two people would need an account, and an account is the thing I was not building. The backup file is how a grid moves, and you move it.
No promise that 8 habits is enough for a whole life. It is enough for one printed page. If you need a ninth, the page stops and says it holds 8. Split the list, or drop one. I will not shrink the type until the names are unreadable and call that a feature.
The printable does not include a logo you upload, a photo header, or a color per habit. Names, day numbers, boxes. If marks are on, an x. That is the file.
Do this with a month
- Open the sample, or add a habit and check the weekdays. Leave Tuesday off if Tuesday is not a day you do the thing.
- Mark the days you did. Look at an empty day and confirm the earlier marks are still there.
- Read the line under the grid. The month count and the current run are different numbers when there is a gap.
- Download a blank month if you want paper with empty boxes. Turn on Include marks only if the x marks are what you want on that sheet.
- Download backup if this browser is not the only place the grid should live. On the other machine, Check backup, read the count, then Replace the grid.
If you wanted holidays on a wall month, use the calendar. If you wanted the row of habits, stay here. A miss is a gap. The days before it stay marked.
Last updated: September 22, 2026 | Reading time: 11 minutes
Written by Softery.io, which would rather keep 1 Sep than congratulate you on a run.