API reference

Performance timing

13/14Coverage9/14Strict (zero caveats)

Wall-clock and monotonic timing grouped together, the way real JS/Node group them. Date follows the host's time zone as Node's does (local getters, the component constructor, toString), with Invalid Date for an unparseable string. A Date is an object, so `===` compares identity and a setter changes the one Date every reference sees; the remaining divergence is that a zone outside the built-in name table prints its abbreviation in toString. performance and perf_hooks are Node's own user-timing code ported to TypeScript: marks and measures are entries on a timeline, observers receive them on a later turn of the loop, and histograms time the event loop.

Exact Works, with caveats Not supported

performance.now()

Exact
performance.now(): number

Milliseconds since the program's time origin (process start), as a double. The origin is captured once at process start, matching the spec's origin-relative reading; the clock is monotonic and nanosecond-grained, like libuv's uv_hrtime. Unlike Date.now(), it is not tied to wall-clock time.

Returns

number — Milliseconds since process start, as a double.

const t1: number = performance.now()
for (let i = 0; i < 200000; i++) { arr.push(i) }
const t2: number = performance.now()
console.log(t2 >= t1)      // true
See it in a full example →

performance.mark / measure / getEntries* / clearMarks / clearMeasures / timerify / timeOrigin

Exact
performance.mark(name: string, options?: PerformanceMarkOptions): PerformanceMark; performance.measure(name: string, startMark?: string, endMark?: string): PerformanceMeasure; performance.measure(name: string, options: PerformanceMeasureOptions): PerformanceMeasure

User timing as Node keeps it. mark(name) records a PerformanceMark (with an optional structured-cloned detail and startTime); measure(name, start?, end?) or measure(name, options) records a PerformanceMeasure spanning two marks or timestamps, through now when the end is omitted. getEntries/getEntriesByName/getEntriesByType read the timeline in start order; a mark that was never set throws a SyntaxError DOMException.

Returns

PerformanceMark | PerformanceMeasure — The recorded entry.

performance.mark("loop-start")
for (let i = 0; i < 200000; i++) { arr2.push(i) }
performance.mark("loop-end")
const loopMs: number = performance.measure("loop", "loop-start", "loop-end").duration
See it in a full example →

Date

Works, with caveats
new Date(); new Date(ms); new Date(isoString); new Date(year, month, day?, hours?, minutes?, seconds?, ms?)

A thin wrapper over milliseconds-since-epoch. Constructs from no argument (now), a millisecond number, an ISO string, or year/month/day/... fields (month 0-indexed, omitted trailing fields defaulting like real JS). Provides the local getFullYear/Month/Date/Day/Hours/Minutes/Seconds/Milliseconds and their getUTC* forms, getTimezoneOffset, getTime/valueOf, toISOString and toString, in the host's time zone as Node's are. The set* and setUTC* setters write the time value back. An unparseable string, NaN or a time past ±8.64e15 ms makes an Invalid Date, whose getters are all NaN.

Returns

Date — A Date value (a plain number under the hood).

const epoch: Date = new Date(0)
console.log(epoch.getFullYear())       // 1970
const later: Date = new Date(1700000000000)
console.log(later.toISOString())
See it in a full example →
⚠ Differences from standard
  • toString's zone name comes from a built-in table of the common zones' abbreviations; a zone outside it prints the C library's abbreviation (GMT-0300 (-03) where Node says (Brasilia Standard Time))

Date.now()

Exact
Date.now(): number

Milliseconds since the epoch, via clock_gettime(CLOCK_REALTIME, ...). Wall-clock time, unlike performance.now().

Returns

number — Milliseconds since the Unix epoch.

const nowMs: number = Date.now()
const now: Date = new Date()
See it in a full example →

Date.parse(string)

Exact
Date.parse(string: string): number

Parses the ECMAScript date-time format (a date-only form as UTC, a date-time without an offset as local time, Z or a +HH:MM/-HH:MM offset) and V8's legacy forms: toString and toUTCString output, "Jul 15 2024", "2024/07/15 10:30".

Returns

number — Milliseconds since epoch, or NaN if unparseable.

console.log(Date.parse('2023-11-14T22:13:20.000Z'))   // 1700000000000
console.log(Date.parse('2023-11-14'))                 // 1699920000000
console.log(Date.parse('not a date'))                 // NaN
See it in a full example →

Date setters (setFullYear, setMonth, setDate, setHours, setMinutes, setSeconds, setMilliseconds, setTime)

Exact
date.setFullYear(y: number, m?: number, d?: number): number // and setMonth/setDate/setHours/setMinutes/setSeconds/setMilliseconds/setTime

Mutate the Date in place, whatever the receiver (a variable, a field, an element, a call result), and return the new time value, matching real JS.

Returns

number — The new timestamp after mutation.

const editable: Date = new Date(0)
const newTimestamp: number = editable.setFullYear(2020)
editable.setMonth(5)
editable.setDate(15)
See it in a full example →

Date arithmetic (date ± durationMs, date - date, date += durationMs)

Exact
date + durationMs; date - durationMs; date - date; date += durationMs

TypeScript rejects arithmetic on a Date, and so does the default strict lane (a compound date += n too): the millisecond count is getTime(). Under -compat=js, date + x concatenates the date string, date - x reads its millisecond count, and date += n makes the variable that string, matching real JS.

Returns

string | number — A string for +; a number for -, *, / and %.

const start: Date = new Date(0)
const tomorrow: Date = new Date(start.getTime() + oneDayMs)
const elapsedMs: number = tomorrow.getTime() - start.getTime()
console.log(elapsedMs)                      // 86400000
See it in a full example →

Date.prototype.toDateString()

Exact
date.toDateString(): string

A fixed "Www Mon DD YYYY" shape (e.g. "Thu Jan 01 1970") in local time, as real JS gives it.

Returns

string — The date as a "Www Mon DD YYYY" string.

const launch: Date = new Date(1700000000000)
console.log(launch.toDateString())          // Tue Nov 14 2023
See it in a full example →

Date.prototype.toLocaleDateString()

Works, with caveats
date.toLocaleDateString(): string

Mimics real JS's default (en-US, no explicit locale) "M/D/YYYY" output.

Returns

string — The date as a "M/D/YYYY" string.

const launch: Date = new Date(1700000000000)
console.log(launch.toLocaleDateString())    // 11/14/2023
See it in a full example →
⚠ Differences from standard
  • One fixed "M/D/YYYY" format (the default en-US shape) in local time; no locale argument or full Intl-style locale support

Date.prototype.toTimeString() / toJSON()

Exact
date.toTimeString(): string · date.toJSON(): string

toTimeString is toString's time and zone part, in local time; toJSON is toISOString, and null for an Invalid Date (what JSON.stringify writes for one).

Returns

string — "13:04:09 GMT+0000 (Coordinated Universal Time)", or the ISO form.

const d = new Date(Date.UTC(2020, 0, 5, 13, 4, 9))
console.log(d.toJSON())            // 2020-01-05T13:04:09.000Z
console.log(new Date(NaN).toJSON()) // null
See it in a full example →

Date.prototype.toLocaleTimeString() / toLocaleString()

Works, with caveats
date.toLocaleTimeString(): string · date.toLocaleString(): string

The default en-US shapes in local time: "1:04:09 PM", and the date with it, "1/5/2020, 1:04:09 PM".

Returns

string — The local time, or date and time, in en-US form.

const d = new Date(Date.UTC(2020, 0, 5, 13, 4, 9))
console.log(d.toLocaleString()) // 1/5/2020, 1:04:09 PM (TZ=UTC)
See it in a full example →
⚠ Differences from standard
  • One fixed en-US shape; no locale argument or full Intl-style locale support

PerformanceObserver

Exact
new PerformanceObserver(callback: (list) => void)

Observes performance entries. observe({ entryTypes }) or observe({ type, buffered }) subscribes; the callback receives a PerformanceObserverEntryList (sorted by start time) on a later turn of the event loop, as in Node. disconnect() and takeRecords() work, and supportedEntryTypes lists the known types.

Parameters
callback(list) => void
Invoked with the entry list.
Returns

PerformanceObserver — The observer handle.

import { PerformanceObserver } from 'perf_hooks'
const obs = new PerformanceObserver((list) => {
  for (const e of list.getEntries()) console.log(e.name, e.duration)
})
obs.observe({ entryTypes: ['measure'] })
performance.mark('a'); performance.mark('b')
performance.measure('a-b', 'a', 'b')

createHistogram / monitorEventLoopDelay

Works, with caveats
createHistogram(options?: CreateHistogramOptions): RecordableHistogram; monitorEventLoopDelay(options?: EventLoopMonitorOptions): IntervalHistogram

perf_hooks histograms: a RecordableHistogram takes record(value)/recordDelta()/add(other); monitorEventLoopDelay samples how late an interval timer runs while enabled. Both report count, min, max, mean, stddev, exceeds and percentiles, with BigInt forms.

Returns

RecordableHistogram | IntervalHistogram — The histogram.

import { createHistogram } from 'perf_hooks'
const h = createHistogram()
h.record(5); h.record(10); h.record(15)
console.log(h.count, h.min, h.max, h.percentile(50))   // 3 5 15 10
See it in a full example →
⚠ Differences from standard
  • A histogram keeps exact samples, not Node's HDR histogram (3 significant figures): a percentile of large values can differ in its last digits