Why Your Project Still Uses Moment.js (And How to Migrate)
The article explains why Moment.js persists despite maintenance mode since 2020, shows how to audit its usage, and provides three migration paths — Day.js for minimal changes, date-fns for functional API, and native Intl for formatting-only needs — with concrete steps, plugin requirements, and bundle size comparisons.
First, confirm how many Moment instances are in your project
Run npm ls moment to see where Moment appears. If it shows up under a third-party dependency, you cannot remove it directly. If it appears in your top-level dependencies, a colleague or AI assistant likely added it.
Next, check actual usage in code: grep -r "moment(" src/ | head -50 Count the distinct APIs used. Most projects only use format, add, diff, startOf, endOf. Few actually need moment-timezone or complex locale logic.
Replacement options: choose based on your situation
Option 1: Minimal changes → Day.js
Day.js API is highly compatible with Moment. dayjs().add(1, 'day').format('YYYY-MM-DD') works the same way. Bundle size is ~2KB and it is immutable by default.
Steps: npm install dayjs Global search-and-replace:
<code>import</code> moment <code>from</code> <code>'moment'</code> → <code>import</code> dayjs <code>from</code> <code>'dayjs'</code>
moment( → dayjs(Run tests. Common breakage points:
.fromNow() : requires dayjs/plugin/relativeTime Timezone operations : need dayjs/plugin/utc and dayjs/plugin/timezone moment.duration() : Day.js duration is a plugin with different method names
moment.locale('zh-cn') : must import locale files separately
Migrate incrementally: change one file, verify, then proceed.
Option 2: Accept functional API → date-fns
date-fns is a pure function library; each function returns a new value without mutating input. It supports tree-shaking natively, so final bundle size depends on imported functions — typically an order of magnitude smaller than Moment.
Trade-off: syntax changes.
<code>// Moment / Day.js</code>
moment(date).add(1, 'day').format('YYYY-MM-DD')
<code>// date-fns</code>
<code>import</code> { addDays, format } <code>from</code> <code>'date-fns'</code>
format(addDays(date, 1), 'yyyy-MM-dd')Format tokens differ — this is the most bug-prone part of migration. Moment's YYYY becomes yyyy in date-fns; DD and dd have different meanings. After migrating, add snapshot tests for formatted output.
Option 3: Only formatting and relative time → native Intl
If you only need display (no date arithmetic), browser-built-in Intl.DateTimeFormat and Intl.RelativeTimeFormat work with zero dependencies:
<code>new</code> <code>Intl</code>.<code>DateTimeFormat</code>(<code>'zh-CN'</code>, { <code>dateStyle</code>: <code>'full'</code> }).<code>format</code>(<code>new</code> <code>Date</code>())
<code>// "2026年10月27日星期二"</code>No installation needed. Suitable for pure presentation-layer formatting.
An often-overlooked point: what maintenance mode actually means
The August 2026 status update revised earlier absolute statements: Moment still receives critical security fixes, moment-timezone continues to update IANA data, and a 3.0 release (maintenance-only, no new features) is not ruled out.
Therefore, "maintenance mode" does not equal "has security vulnerabilities" nor "will break tomorrow."
Appendix: bundle size numbers
Moment minified+gzipped is ~72KB, does not support tree-shaking — all code ships regardless of usage. Day.js is ~2KB. date-fns, when imported selectively, usually ends up under 10KB in the final bundle.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
JavaScript
Provides JavaScript enthusiasts with tutorials and experience sharing on web front‑end technologies, including JavaScript, Node.js, Deno, Vue.js, React, Angular, HTML5, CSS3, and more.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
