Working with Dates using date-fns in JavaScript

default image

Hey there! Dates are complex beasts in JavaScript. Thankfully, the handy date-fns library makes wrangling dates a breeze.

In this comprehensive guide, you‘ll learn how to leverage date-fns to handle any date scenario imaginable. By the end, you‘ll be a date wrangling expert!

Why is Working with Dates Hard?

Before we dive into date-fns, let‘s explore why working with dates in JavaScript is so challenging:

  • Timezones – The huge variety of timezones worldwide makes working with dates difficult.

  • Inconsistent interfaces – The native JavaScript Date object has a notoriously bad API.

  • Globalization – Formatting and localizing dates is complex with internationalization.

  • Immutability – Dates are mutable in JavaScript, leading to weird bugs if you modify them.

  • Calculation errors – It‘s easy to make mistakes when manually calculating with dates.

These factors combine to make working with dates a headache!

date-fns to the Rescue!

date-fns provides a clean and consistent API for manipulating, formatting, and calculating with JavaScript dates.

Here are some standout benefits of using date-fns:

  • Intuitive naming – Methods like format, addDays, isBefore make sense.

  • Immutable dates – Original dates aren‘t mutated, avoiding bugs.

  • Localization – Built-in support for internationalization.

  • Tree-shakable– Only import what you need to optimize bundle size.

  • Battle tested – Over 2 billion downloads and used by major companies.

To get started, install date-fns with npm:

npm install date-fns 

Now let‘s go over some essential date-fns methods.

Core date-fns Methods

date-fns provides a ton of useful functions. Here are some of the most common ones:


To validate if a date is real:

import { isValid } from ‘date-fns‘

isValid(new Date(‘2021-02-30‘)) // false - not a real date!
isValid(new Date(‘2021-03-01‘)) // true 

This avoids issues with invalid dates in JavaScript silently failing.


To parse a string into a date:

import { parse } from ‘date-fns‘

parse(‘03/25/2021‘, ‘MM/dd/yyyy‘, new Date()) 

parse allows specifying the format so you can accurately parse any date string.


To format a date string:

import { format } from ‘date-fns‘

format(new Date(), ‘yyyy-MM-dd‘) // 2021-11-26
format(new Date(), ‘do MMM yyyy‘) // 26th Nov 2021  

Super handy for outputting dates in any format you want.

add, sub

To add and subtract date components:

import { addDays, subWeeks } from ‘date-fns‘

const date = new Date()

addDays(date, 5) // 5 days after date
subWeeks(date, 2) // 2 weeks before date

You can add/subtract years, months, days, hours, minutes, seconds etc.


To get a human readable date difference:

import { distanceInWords } from ‘date-fns‘

// Date tomorrow 
const tomorrow = addDays(new Date(), 1) 

// Will output "1 day"
distanceInWords(new Date(), tomorrow)  

This makes it easy to display friendly date differences.

There are many more useful date-fns methods like min, max, differenceInDays, isSameMonth and so on.

Now let‘s go over some advanced use cases.

Advanced Usage of date-fns

You can build some powerful date logic with date-fns‘ advanced functions.

Flexible Manipulation

To manipulate date components:

import { getYear, setMonth, addDays } from ‘date-fns‘

const date = new Date()

// Get year 

// Set month
setMonth(date, 3)  

// Add days
addDays(date, 10)

Being able to get, set, and add/subtract any date part is super handy.

Intelligent Comparisons

To compare dates:

import { isAfter, isBefore, isEqual } from ‘date-fns‘

const date1 = new Date(2021, 0, 1)
const date2 = new Date(2021, 0, 2) 

isAfter(date1, date2) // false
isBefore(date1, date2) // true
isEqual(date1, date2) // false

This makes complex date comparisons much simpler.


To format dates locally:

import { format, eoLocale } from ‘date-fns‘

// Esperanto locale
format(new Date(), ‘do MMMM yyyy‘, { locale: eoLocale })
// ‘2-a de decembro 2022‘ 

No need to reinvent the wheel for I18n – just use built-in locales!

Relative Ranges

To get dates within a range:

import { eachDayOfInterval } from ‘date-fns‘

const start = new Date(2022, 0, 1)
const end = new Date(2022, 0, 10)

eachDayOfInterval({start, end}).forEach(day => {
  // Loops through Jan 1 to Jan 10

Makes it easy to iterate through date ranges.

There are many more powerful date calculation and manipulation functions available.

Now let‘s go over some common real-world examples.

Handling Date Scenarios with date-fns

Here are some useful examples of how to leverage date-fns in real apps.

Displaying Dates Nicely

To output nicely formatted dates:

// March 5th, 2022
format(date, ‘MMMM do, yyyy‘)

// 2022-03-05
format(date, ‘yyyy-MM-dd‘)  

No more ugly default JavaScript date formatting!

Scheduling Future Events

To plan events in the future:

// 3 days from today 
const threeDaysFromNow = addDays(new Date(), 3)

// 2 weeks from today
const twoWeeksFromNow = addWeeks(new Date(), 2)

This is great for scheduling events, reminders, calendars etc.

Birthday Notifications

To get upcoming birthdays:

// Birthday February 22nd 
const birthday = new Date(2022, 1, 22) 

// Check if within 30 days
isWithinInterval(birthday, {
  start: new Date(),
  end: addDays(new Date(), 30) 

// If so, send notification!

Help users remember important dates automatically.

Post Timestamps

To display friendly timestamps:

// Post submitted 15 min ago
formatDistance(new Date(), submittedDate) 

// Updated 1 hour ago
formatDistance(new Date(), updatedDate) 

Cleaner than showing raw timestamps.

There are infinite use cases for dates in apps – date-fns likely has you covered!

Now let‘s go over some best practices.

Best Practices for date-fns

Here are some tips for using date-fns effectively:

  • Favor immutability over mutation – avoids weird bugs!
  • Be timezone aware – set options like {awareOfUnicodeTokens: true}.
  • Leverage built-in locales for international dates.
  • Tree-shake to optimize bundle size by removing unused code.
  • Compare performance to native APIs for simple cases.
  • Follow Code Style Guidelines for clean and consistent code.

And some quick statistics:

  • 2+ billion downloads
  • Used by companies like Google, Amazon, Twitter, React
  • 225+ functions available
  • Supports 35+ languages

Following these best practices will ensure you properly leverage the date-fns library.


Phew, that was a whirlwind tour of how date-fns makes working with dates in JavaScript enjoyable instead of frustrating!

The key takeaways are:

  • date-fns provides an intuitive API for dates
  • Tons of useful manipulation, formatting, and localization helpers
  • Ideal for complex date logic like ranges and comparisons
  • Used by many large tech companies

To recap, date-fns is the perfect tool for your date manipulation needs in JavaScript. The handy functions, immutable dates and robust localization make it a must for any serious web app.

I hope this guide gives you confidence in wrangling any date problem with JavaScript and date-fns! Let me know if you have any other questions.

Happy coding!

Written by