Look, I'll be real with you. JavaScript's Date object is a disaster.
Every time I needed to format a date, I'd find myself Googling "javascript format date" for the hundredth time. Every time I needed to do date math, I triple-checked the math because I didn't trust how it handled months. Don't even get me started on trying to add days to a date without accidentally mutating the original.
After years of this nonsense, I finally went for it. I was working on a project that needed a lot of date manipulation, and I realized I was spending more time wrestling with dates and building composable functions than actually building features. So I did what any self-respecting developer would do: I built my own solution.
Enter WristWatch
WristWatch is my answer to JavaScript's date problems. It's a tiny library (less than 10KB) with zero dependencies that wraps the native Date API in a way that actually makes sense (at least to me).
Here's the thing: I didn't want to build some massive framework like Moment.js. I just wanted something that would let me:
- Format dates without checking the docs every time
- Do date math without crying
- Remember function names without a PhD in JavaScript archaeology
- Not accidentally mutate dates and break everything
The Fun Parts
Months That Make Sense
This was the first thing I fixed. Native Date.getMonth() returns 0-11. This is because it's based on Java's old date API and I'm actually cool with that. However, I still needed to account for the zero-based months in my code. In WristWatch, months are 1-12 like a normal human would expect:
const date = new WristWatch('2025-12-05');
date.getMonth(); // 12 (December, not 11!)
Formatting That Doesn't Suck
Want to format a date? Just tell it what you want:
const now = WristWatch.now();
now.format('YYYY-MM-DD'); // "2025-12-06"
now.format('MMMM D, YYYY'); // "December 6, 2025"
now.toRelative(); // "just now"
No more chaining together a dozen methods or importing an entire formatting library.
Date Math That Actually Works
Adding days to a date should be easy. In WristWatch, it is:
const today = WristWatch.now();
const tomorrow = today.add(1, 'day');
const nextWeek = today.add(1, 'week');
const nextMonth = today.add(1, 'month');
Everything's immutable, so you can't accidentally mess up your original date. And it handles all the annoying edge cases like "what happens when I add a month to January 31st?" (Answer: you get February 28th, not March 3rd.)
Comparisons That Don't Make You Think
Need to check if one date is before another? Just do it:
if (tomorrow.isAfter(today)) {
console.log('Tomorrow is in the future!');
}
if (date.isBetween(start, end)) {
console.log('Date is in range!');
}
No timestamp subtraction, no mental math, just straightforward comparisons.
The Technical Bits
Zero Dependencies
I hate bloat. WristWatch has exactly zero dependencies. It's just a thin wrapper around the native Date API, which means it's fast, reliable, and won't break when some random dependency decides to deprecate itself. F*ck yeah.
Fully Typed
Written in TypeScript from the ground up. Every function, every parameter, everything is typed. F*ck yeah.
Tree-Shakeable
Only import what you need. Want just the formatting functions? Import just those. F*ck yeah.
// Method chaining style
import { WristWatch } from '@lukelowers/wrist-watch';
const ww = WristWatch.now();
ww.add(1, 'day').format('YYYY-MM-DD');
// Functional style
import { now, format, add } from '@lukelowers/wrist-watch';
const date = now();
format(add(date.getDate(), 1, 'day'), 'YYYY-MM-DD');
Closely Related to the OG Solution
I didn't want to recreate the original, I wanted to iterate on it. Wrist-Watch is a wrapper so it still reminds you of the old ways. I also didn't want to try to compete with popular methods. I just made what I need. F*ck yeah.
Actually Tested
I used property-based testing with fast-check to make sure everything works. Hundreds of random test cases running through every function. The code is also open, so test anything I missed. F*CK YEAH.
The Real Talk
Here's the thing about building a date library: everyone tells you not to do it. "Just use Moment!" they say. "Just use date-fns!" they say.
But Moment is deprecated. date-fns is great but it's huge. And honestly? Sometimes you just want something simple that does exactly what you need without importing half of npm.
WristWatch isn't trying to be everything to everyone. It's trying to be the library I wish existed. Small, focused, and actually pleasant to use.
Want to Try It?
npm install @lukelowers/wrist-watch
The GitHub repo has full docs and examples. PRs welcome if you find something broken or want to add a feature.
Did I over-complicate this? IDK, probably. Did I enjoy building it? Definitely. Will I use it in every project from now on? F*ck yeah.
Sometimes you just need to scratch your own itch. This was mine.
Top comments (0)