Building the cron builder for Quietbench, I started with an npm package for parsing and calculating next-run times. Get it working, move on. That lasted about a week.

The problem: the library handled standard cron fine, but broke on real edge cases — conditional OR/AND behavior when day-of-week and day-of-month are combined, step values inside ranges (1-10/2), and off-by-one errors around DST transitions. When I checked its output against standard cron engines, the mismatches showed up fast.

Why not patch it: the parsing and "next run time" logic were tightly coupled internally. Fixing one edge case risked breaking another. Writing something scoped to exactly what I needed was less work than fighting someone else's abstraction.

The rewrite keeps three things cleanly separate: tokenize/validate each field, normalize day-of-week/day-of-month interaction explicitly, and compute next executions by walking forward in time rather than solving algebraically. Slower in theory, irrelevant in practice — nobody notices a few milliseconds when they're reading 5 output times.

Building the cron builder for Quietbench, I started with an npm package for parsing and calculating next-run times. Get it working, move on. That lasted about a week.