Tuesday, May 26, 2026Tech HubAboutContactAdvertiseNewsletter
Back to Home
Moving From Moment.js To The JS Temporal API

Moving From Moment.js To The JS Temporal API

The way JavaScript handles time has evolved significantly, from the built-in `Date` API to Moment.js and now Temporal. The new standard fills gaps in the original `Date` API while addressing limitations found in Moment and other libraries. Joe Attardi shares practical “recipes” for migrating...

B
Blizine Admin
·1 min read·0 views

Moving From Moment.js To The JS Temporal API — Smashing Magazine

Skip to main content Start reading the article Jump to list of all articles Jump to all topics18 min readJavaScript, API, CodingShare on Twitter, LinkedInAbout The AuthorJoe Attardi has been building beautiful and functional web applications for over 20 years. He is passionate about front-end development and modern JavaScript … More about Joe ↬Email NewsletterYour (smashing) email Weekly tips on front-end & UX.Trusted by 182,000+ folks. See User Testing Live Custom Web Forms for Angular, React, & Vue. Your backend. How To Measure UX and Design Impact, 8h video + UX training Naming Design Systems with Samantha Gordashko Building Modern HTML Emails with Rémi Parmentier Celebrating 10 million developers How To Measure UX and Design Impact, 8h video + UX trainingThe way JavaScript handles time has evolved significantly, from the built-in Date API to Moment.js and now Temporal. The new standard fills gaps in the original Date API while addressing limitations found in Moment and other libraries. Joe Attardi shares practical “recipes” for migrating Moment-based code to the new Temporal API.Almost any kind of application written in JavaScript works with times or dates in some capacity. In the beginning, this was limited to the built-in Date API. This API includes basic functionality, but is quite limited in what it can do.Third-party libraries like Moment.js, and later built-in APIs such as the Intl APIs and the new Temporal API, add much greater flexibility to working with times and dates.The Rise And Fall Of Moment.jsMoment.js is a JavaScript library with powerful utilities for working with times and dates. It includes missing features from the basic Date API, such as time zone manipulation, and makes many common operations simpler. Moment also includes functions for formatting dates and times. It became a widely used library in many different applications.However, Moment also had its share of issues. It’s a large library, and can add significantly to an application’s bundle size. Because the library doesn’t support tree shaking (a feature of modern bundlers that can remove unused parts of libraries), the entire Moment library is included even if you only use one or two of its functions.Another issue with Moment is the fact that the objects it creates are mutable. Calling certain functions on a Moment object has side effects and mutates the value of that object. This can lead to unexpected behavior or bugs.In 2020, the maintainers of Moment decided to put the library into maintenance mode. No new feature development is being done, and the maintainers recommend against using it for new projects.There are other JavaScript date libraries, such as date-fns, but there’s a new player in town, an API built directly into JavaScript: Temporal. It’s a new standard that fills in the holes of the original Date API as well as solves some of the limitations found in Moment and other libraries.What Is Temporal?Temporal is a new time and date API being added to the ECMAScript standard, which defines modern JavaScript. As of March 2026, it has reached Stage 4 of the TC39 process (the committee that oversees proposals and additions to the JavaScript language), and will be included in the next version of the ECMAScript specification. It has already been implemented in several browsers: Chrome 144+ and Firefox 139+, with Safari expected to follow soon. A polyfill is also available for unsupported browsers and Node.js.The Temporal API creates objects that, generally, represent moments in time. These can be full-time and date stamps in a given time zone, or they can be a generic instance of “wall clock” time without any time zone or date information. Some of the main features of Temporal include:Times with or without dates.A Temporal object can represent a specific time on a specific date, or a time without any date information. A specific date, without a time, can also be represented.Time zone support.Temporal objects are fully time zone aware and can be converted across different time zones. Moment supports time zones, too, but it requires the additional moment-timezone library.Immutability.Once a Temporal object is created, it cannot be changed. Time arithmetic or time zone conversions do not modify the underlying object. Instead, they generate a new Temporal object.1-based indexing.A common source of bugs with the Date API (as well as with Moment) is that months are zero-indexed. This means that January is month 0, rather than month 1 as we all understand in real life. Temporal fixes this by using 1-based indexing — January is month 1.It’s built into the browser.Since Temporal is an API in the browser itself, it adds nothing to your application’s bundle size.It’s also important to note that the Date API isn’t going away. While Temporal supersedes this API, it is not being removed or deprecated. Many applications would break if browsers suddenly removed the Date API. However, also keep in mind that Moment is now considered a legacy project in maintenance mode.In the rest of the article, we’ll look at some “recipes” for migrating Moment-based code to the new Temporal API. Let’s start refactoring!Creating Date And Time ObjectsBefore we can manipulate dates and times, we have to create objects representing them. To create a Moment object representing the current date and time, use the moment function.const now = moment(); console.log(now); // Moment This object can now be formatted or manipulated as needed.// convert to UTC // warning: This mutates the Moment object and puts it in UTC mode! console.log(now.utc()); // Moment

// print a formatted string - note that it's using the UTC time now console.log(now.format('MM/DD/YYYY hh:mm:ss a')); // 02/19/2026 02:27:07 am The key thing to remember about Moment is that a Moment object always includes information about the time and the date. If you only need to work with time information, this is usually fine, but it can cause unexpected behavior in situations like Daylight Saving Time or leap years, where the date can have an effect on time calculations.Temporal is more flexible. You can create an object representing the current date and time by creating a Temporal.Instant object. This represents a point in time defined by the time since “the epoch” (midnight UTC on January 1, 1970). Temporal can reference this instant in time with nanosecond-level precision.const now = Temporal.Now.instant();

// see raw nanoseconds since the epoch console.log(now.epochNanoseconds); // 1771466342612000000n

// format for UTC console.log(now.toString()); // 2026-02-19T01:55:27.844Z

// format for a particular time zone console.log(now.toString({ timeZone: 'America/New_York' })); // 2026-02-18T20:56:57.905-05:00 Temporal.Instant objects can also be created for a specific time and date by using the from static method.const myInstant = Temporal.Instant.from('2026-02-18T21:10:00-05:00');

// Format the instant in the local time zone. Note that this only controls // the formatting - it does not mutate the object like `moment.utc` does. console.log(myInstant.toString({ timeZone: 'America/New_York' })); // 2026-02-18T21:10:00-05:00 You can also create other types of Temporal objects, including:Temporal.PlainDate: A date with no time information.Temporal.PlainTime: A time with no date information.Temporal.ZonedDateTime: A date and time in a specific time zone.Each of these has a from method that can be called with an object specifying the date and/or time, or a date string to parse.// Just a date const today = Temporal.PlainDate.from({ year: 2026, month: 2, // note we're using 2 for February day: 18 }); console.log(today.toString()); // 2026-02-18

// Just a time const lunchTime = Temporal.PlainTime.from({ hour: 12 }); console.log(lunchTime.toString()); // 12:00:00

// A date and time in the US Eastern time zone const dueAt = Temporal.ZonedDateTime.from({ timeZone: 'America/New_York', year: 2026, month: 3, day: 1, hour: 12, minute: 0, second: 0 }); console.log(dueAt.toString()); // 2026-03-01T12:00:00-05:00[America/New_York] ParsingWe’ve covered programmatic creation of date and time information. Now let’s look at parsing. Parsing is one area where Moment is more flexible than the built-in Temporal API.You can parse a date string by passing it to the moment function. With a single argument, Moment expects an ISO date string, but you can use alternative formats if you provide a second argument specifying the date format being used.const isoDate = moment('2026-02-21T09:00:00'); const formattedDate = moment('2/21/26 9:00:00', 'M/D/YY h:mm:ss');

console.log(isoDate); // Moment

console.log(formattedDate); // Moment In older versions, Moment would make a best guess to parse any arbitrarily formatted date string. This could lead to unpredictable results. For example, is 02-03-2026 February 2 or March 3? For this reason, newer versions of Moment display a prominent deprecation warning if it’s called without an ISO formatted date string (unless the second argument with the desired format is also given).Temporal will only parse a specifically formatted date string. The string must be compliant with the ISO 8601 format or its extension, RFC 9557. If a non-compliant date string is passed to a from method, Temporal will throw a RangeError.// Using an RFC 9557 date string const myDate = Temporal.Instant.from('2026-02-21T09:00:00-05:00[America/New_York]'); console.log(myDate.toString({ timeZone: 'America/New_York' })); // 2026-02-21T09:00:00-05:00

// Using an unknown date string const otherDate = Temporal.Instant.from('2/21/26 9:00:00'); // RangeError: Temporal error: Invalid character while parsing year value. The exact requirements of the date string depend on which kind of Temporal object you’re creating. In the above example, Temporal.Instant requires a full ISO 8601 or RFC 9557 date

📰Originally published at smashingmagazine.com

Comments