npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

precise-time-ntp

v2.1.2

Published

⏰ Simple NTP time sync for Node.js - Auto-drift, WebSocket & HTML clocks

Readme

precise-time-ntp

OpenSSF Baseline OpenSSF Best Practices

Sync your Node.js app with NTP servers and get the real time.

Your system clock drifts. Servers disagree. Date.now() lies. This library fixes that with a proper 4-timestamp NTP implementation that compensates for network latency, validates server consistency, and corrects drift gradually without breaking your running timers.


Install

npm install precise-time-ntp

Quick start

const timeSync = require('precise-time-ntp');

await timeSync.sync();

timeSync.now()        // Date object — precise NTP time
timeSync.timestamp()  // "2026-04-25T15:30:45.123Z"
timeSync.offset()     // how far off your system clock is, in ms

Configuration

See the 📖 Documentation

All options can be set at construction time or overridden per sync() call.

const { TimeSync } = require('precise-time-ntp');

const t = new TimeSync({
    // NTP servers to query (up to 3 are used for coherence validation)
    servers: ['time.cloudflare.com', 'time.google.com', 'pool.ntp.org'],

    timeout: 5000,             // ms before a server is considered unreachable
    coherenceValidation: true, // compare servers and use median offset

    // Auto-sync on startup
    autoSync: true,
    autoSyncInterval: 300000,  // re-sync every 5 minutes

    // Smooth correction (see section below)
    smoothCorrection: true,
    maxCorrectionJump: 1000,  // ms — apply instantly if diff is under this
    correctionRate: 0.1,      // fraction per sync cycle (0.1 = 10%)
    maxOffsetThreshold: 5000, // ms — always apply instantly if diff exceeds this

    locale: 'fr-FR',           // used by format() — defaults to system locale
});

Or pass options directly to sync() for a one-off override:

await timeSync.sync({
    servers: ['time.cloudflare.com'],
    timeout: 3000,
    coherenceValidation: false,
});

The default global instance uses pool.ntp.org, time.google.com, and time.cloudflare.com.


Keep it synced automatically

await timeSync.sync();
timeSync.startAutoSync(300000); // ms — re-sync every 5 minutes

Or enable it at construction: new TimeSync({ autoSync: true, autoSyncInterval: 300000 }).

coherenceValidation queries multiple servers and uses the median offset — useful if one server is having a bad day. Emits a coherenceWarning event if servers disagree by more than 100ms.


Smooth correction

By default, if your clock is off by 500ms and you re-sync, it jumps 500ms instantly. That can break timers and logs. Smooth correction applies the fix gradually:

timeSync.setSmoothCorrection(true, {
    maxCorrectionJump: 1000,  // ms — apply instantly if diff is under 1s
    correctionRate: 0.1,      // fraction per sync cycle (0.1 = 10%)
    maxOffsetThreshold: 5000  // ms — always apply instantly if diff > 5s
});

// If you can't wait for the gradual correction to finish:
timeSync.forceCorrection();

Utilities

// Format current NTP time (pass null as first argument to use NTP time)
timeSync.format(null, 'iso')              // "2026-04-25T15:30:45.123Z"
timeSync.format(null, 'locale')           // system locale, e.g. "25/04/2026, 17:30:45"
timeSync.format(null, 'locale', 'en-US') // "4/25/2026, 5:30:45 PM"
timeSync.format(null, 'utc')             // "Sat, 25 Apr 2026 15:30:45 GMT"
timeSync.format(null, 'date')            // date only
timeSync.format(null, 'time')            // time only
timeSync.format(null, 'timestamp')       // Unix timestamp as string

// Format a specific date
timeSync.format('2026-01-01', 'iso')     // "2026-01-01T00:00:00.000Z"
timeSync.format(new Date(), 'locale')    // any Date object works too

// Difference between two dates — returns ms
timeSync.diff('2026-01-01', timeSync.now()) // e.g. 9849600000 ms

// console.log with NTP timestamp prefix
timeSync.log('order processed')
// → [2026-04-25T15:30:45.123Z] order processed

// Check sync status without throwing
if (timeSync.isSynchronized()) {
    console.log(timeSync.now());
}

Live HTML clock via WebSocket

// server.js
await timeSync.sync();
timeSync.startWebSocketServer(8080);
timeSync.startAutoSync(300000);
<h1 id="clock"></h1>
<script>
const ws = new WebSocket('ws://localhost:8080');
ws.onmessage = (e) => {
    const { data } = JSON.parse(e.data);
    document.getElementById('clock').textContent =
        new Date(data.timestamp).toLocaleTimeString();
};
</script>

Events

timeSync.on('sync', (data) => {
    // data.server, data.offset (ms), data.rtt (ms)
    console.log(`synced — offset: ${data.offset}ms, rtt: ${data.rtt}ms`);
});

timeSync.on('error', (err) => {
    // err.message, err.server
    console.error(`sync failed on ${err.server}: ${err.message}`);
});

timeSync.on('coherenceWarning', (data) => {
    // servers disagree by more than 100ms
    console.warn(`server variance: ${data.variance}ms`, data.servers);
});

timeSync.on('driftWarning', (data) => {
    // now() called more than 1 hour after last sync
    console.warn(`${(data.elapsed / 3600000).toFixed(1)}h since last sync`);
});

timeSync.on('correctionComplete', (data) => {
    // data.finalOffset, data.converged, data.forced, data.timeout
    console.log(`correction done — final offset: ${data.finalOffset}ms`);
});

Stats

const s = timeSync.stats();

s.synchronized         // true/false
s.offset               // ms — current system clock error
s.rtt                  // ms — last network round-trip time
s.correctedOffset      // ms — offset currently being applied
s.correctionInProgress // true while smooth correction is running
s.lastSync             // Date of last successful sync
s.uptime               // ms since last sync

API

| Method | Description | |--------|-------------| | sync(options?) | Sync with NTP servers | | now() | Current precise time as a Date | | timestamp() | Current time as ISO string | | offset() | System clock error in ms | | isSynchronized() | Returns true if synced (no throw) | | stats() | Full sync diagnostics | | startAutoSync(interval) | Re-sync on an interval (interval in ms) | | stopAutoSync() | Stop auto-sync | | setSmoothCorrection(bool, options?) | Configure gradual correction | | forceCorrection() | Apply pending correction immediately | | startWebSocketServer(port) | Broadcast time over WebSocket | | stopWebSocketServer() | Stop WebSocket server | | format(date?, format?, locale?) | Format a date (iso, locale, utc, date, time, timestamp) | | diff(date1, date2?) | Difference between two dates — returns ms | | log(message) | console.log with NTP timestamp prefix |

Full option reference: docs/api-reference.md


Try it

npm run basic        # simple sync
npm run auto-sync    # auto-sync loop
npm run websocket    # WebSocket + HTML clock

License

MIT

GitHub npm version