Skip to main content
← Back to Blog

Why Your Date Library Should Live in Your Codebase

The shadcn approach to date formatting

Z

ZVN

·6 min read
#typescript#shadcn#architecture

When Shadcn/ui came out, it challenged a fundamental assumption: why do UI components need to be npm packages?

The answer was: they don't. By copying components directly into your codebase, you get full customization without forking, no version lock-in, and code that AI assistants can read and understand.

Whenny applies the same philosophy to date formatting.

The node_modules Problem

Here's what happens when you use a traditional date library:

import { format } from 'date-fns'
const display = format(date, 'yyyy-MM-dd')

Looks simple. But:

  1. AI can't see the implementation - When Claude helps you, it can't read inside node_modules
  2. Format strings are tribal knowledge - Is it YYYY or yyyy? Depends on the library
  3. Customization requires workarounds - Want to change "5 minutes ago" to "5m ago"? Good luck

The shadcn Approach

Whenny installs code directly into your project:

npx create-whenny
npx create-whenny add relative smart duration

This creates:

your-project/
├── lib/
│   └── whenny/
│       ├── core.ts          # Main whenny() function
│       ├── relative.ts      # "5 minutes ago"
│       ├── config.ts        # YOUR configuration
│       └── index.ts         # Exports

You own this code. It's checked into your repo. AI can read it. You can modify it.

Tailwind-Style Configuration

In your lib/whenny/config.ts:

configure({
  styles: {
    xs: 'M/D',
    sm: 'MMM D',
    md: 'MMM D, YYYY',
    lg: 'MMMM Do, YYYY',
  },
  relative: {
    justNow: 'just now',
    minutesAgo: (n) => `${n}m ago`,
  }
})

Now EVERYWHERE in your app, whenny(date).sm gives you consistent output.


Next up: The markdown file that teaches AI your date conventions.