Migrating from moment.js - Complete Guide
moment.js is in maintenance mode. It still works and 2.29.4 has no unpatched CVEs, but new features will not be added and future security fixes are not guaranteed. This guide covers migrating to dayjs (near drop-in) or date-fns (more modern, tree-shakeable).
moment.js has been in maintenance-only mode since September 2020. No new features, no non-security bug fixes. It has 4 known CVEs - all fixed in 2.29.4. Future CVEs may not receive patches.
Choose your replacement
dayjs
Near-identical API to moment.js. 2KB gzipped vs moment 67KB. Most moment.js code works after changing the import.
npm install dayjs
date-fns
Functional API - completely different from moment. Tree-shakeable, TypeScript-first. Better for new code than migration.
npm install date-fns
Luxon
Built by a moment.js author. Wraps the native Intl API. Immutable by default. Best for serious timezone and locale support.
npm install luxon
Temporal API
Upcoming native JavaScript date API. Currently a TC39 proposal with polyfill available.
npm install @js-temporal/polyfill
Option A - Migrate to dayjs (recommended for existing codebases)
Step 1 - Install dayjs and remove moment
npm install dayjs npm uninstall moment
Step 2 - Replace imports
import moment from 'moment';
import dayjs from 'dayjs';
Step 3 - Basic usage
// Parse
moment('2024-01-15')
moment('2024-01-15', 'YYYY-MM-DD')
// Format
moment().format('YYYY-MM-DD')
moment().format('MMMM Do YYYY')
// Manipulate
moment().add(7, 'days')
moment().subtract(1, 'month')
// Compare
moment('2024-01-15').isBefore('2024-06-01')
moment('2024-01-15').isAfter(moment())
// Display
moment().fromNow()
moment().toDate()// Parse
dayjs('2024-01-15')
dayjs('2024-01-15', 'YYYY-MM-DD') // needs customParseFormat plugin
// Format
dayjs().format('YYYY-MM-DD')
dayjs().format('MMMM Do YYYY') // needs advancedFormat plugin
// Manipulate
dayjs().add(7, 'day')
dayjs().subtract(1, 'month')
// Compare
dayjs('2024-01-15').isBefore('2024-06-01')
dayjs('2024-01-15').isAfter(dayjs())
// Display
dayjs().fromNow() // needs relativeTime plugin
dayjs().toDate()Step 4 - Enable plugins you need
import dayjs from 'dayjs' import relativeTime from 'dayjs/plugin/relativeTime' import advancedFormat from 'dayjs/plugin/advancedFormat' import customParseFormat from 'dayjs/plugin/customParseFormat' import timezone from 'dayjs/plugin/timezone' import utc from 'dayjs/plugin/utc' import duration from 'dayjs/plugin/duration' dayjs.extend(relativeTime) dayjs.extend(advancedFormat) dayjs.extend(customParseFormat) dayjs.extend(utc) dayjs.extend(timezone)
Step 5 - Timezone handling
import moment from 'moment-timezone'
moment.tz('2024-01-15 12:00', 'America/New_York')
moment().tz('Europe/London').format()import dayjs from 'dayjs'
import utc from 'dayjs/plugin/utc'
import timezone from 'dayjs/plugin/timezone'
dayjs.extend(utc)
dayjs.extend(timezone)
dayjs.tz('2024-01-15 12:00', 'America/New_York')
dayjs().tz('Europe/London').format()Key differences to watch for
- dayjs objects are immutable - manipulations return new objects
- add() uses singular units: 'day' not 'days'
- moment.duration() requires dayjs/plugin/duration
- moment.utc() requires dayjs/plugin/utc
- fromNow() requires dayjs/plugin/relativeTime
Option B - Migrate to date-fns
date-fns uses a functional API - every operation is a standalone function. Better for greenfield code than migration.
import moment from 'moment'
// Format
moment().format('yyyy-MM-dd')
// Add days
moment().add(7, 'days').toDate()
// Check if before
moment('2024-01-15').isBefore('2024-06-01')
// From now
moment().fromNow()import { format, addDays, isBefore, formatDistanceToNow } from 'date-fns'
// Format
format(new Date(), 'yyyy-MM-dd')
// Add days
addDays(new Date(), 7)
// Check if before
isBefore(new Date('2024-01-15'), new Date('2024-06-01'))
// From now
formatDistanceToNow(new Date(), { addSuffix: true })Check your CVE status first
If you are on moment.js 2.29.4 you have no unpatched CVEs. The migration is about future-proofing, not an emergency.
Check your current dependencies for CVEs before migrating.
Scan with PackageFix →Free · No signup · No CLI · Runs in your browser