cue-ntp is a small TypeScript library for reading time from an NTP server in
Node.js. It sends a UDP NTP client request, parses the server transmit
timestamp, and returns the result as a JavaScript Date.
When you want display-friendly UTC time, pass amPm: true to return a
hh:mm:ss AM/PM string instead.
- Query an NTP server by hostname or IP address.
- Choose the UDP port, timeout, NTP version, socket family, and output format.
- Receive server time as a
Dateby default. - Return UTC time as
hh:mm:ss AM/PMwithamPm: true. - Use ESM or CommonJS builds from
dist/.
Because this library uses Node's node:dgram UDP sockets, it is intended for
Node.js runtimes. Browser apps should call it through a backend API.
This package is currently private, so install it from a local tarball.
Build and package the library:
npm run pack:localInstall the generated tarball in another project:
npm install /path/to/cue-ntp/cue-ntp-0.1.0.tgzIf this package is later published to npm, install it with:
npm install cue-ntpimport { getNtpTime } from "cue-ntp";
const date = await getNtpTime("time.google.com", 123);
console.log(date.toISOString());
const time = await getNtpTime("time.google.com", 123, { amPm: true });
console.log(time);amPm: true formats the server timestamp as UTC time, not local time.
From this project, create a local package tarball:
npm run pack:localThen install that tarball from the project where you want to use the library:
npm install /path/to/cue-ntp/cue-ntp-0.1.0.tgzimport { getNtpTime } from "cue-ntp";Use getNtpTime with a host and port. Port 123 is the standard NTP port.
const date = await getNtpTime("pool.ntp.org", 123);
console.log(date.toISOString());Pass amPm: true when you want a UTC 12-hour time string instead of a Date.
const time = await getNtpTime("pool.ntp.org", 123, { amPm: true });
console.log(time);import { getNtpTime } from "cue-ntp";
async function main() {
try {
const date = await getNtpTime("pool.ntp.org", 123, {
timeoutMs: 5000,
version: 4,
socketType: "udp4"
});
const time = await getNtpTime("pool.ntp.org", 123, {
timeoutMs: 5000,
version: 4,
socketType: "udp4",
amPm: true
});
console.log("ISO timestamp:", date.toISOString());
console.log("UTC AM/PM:", time);
} catch (error) {
console.error(
"Could not read NTP time:",
error instanceof Error ? error.message : error
);
}
}
await main();In this example:
pool.ntp.orgis the NTP host.123is the standard NTP port.timeoutMscontrols how long the request can wait.versionsupports3or4.socketTypesupports"udp4"or"udp6".amPmreturns a UTChh:mm:ss AM/PMstring when set totrue.
Network failures, invalid inputs, malformed responses, and timeouts reject the
returned promise. Wrap calls in try/catch when the request can fail.
function getNtpTime(
ipAddress: string,
port: number,
options?: NtpClientOptions
): Promise<Date | string>;Sends an NTP request to the given hostname or IP address and port.
By default, it resolves with the server transmit timestamp as a Date.
When options.amPm is true, it resolves with UTC time formatted as
hh:mm:ss AM/PM.
The function validates the port, opens a UDP socket, sends a 48-byte NTP request, parses the response, and closes the socket when the request settles.
const date = await getNtpTime("time.google.com", 123);
const time = await getNtpTime("time.google.com", 123, { amPm: true });TypeScript narrows the return type for literal amPm options:
const date = await getNtpTime("time.google.com", 123);
// Date
const time = await getNtpTime("time.google.com", 123, { amPm: true });
// stringinterface NtpClientOptions {
timeoutMs?: number;
version?: 3 | 4;
socketType?: "udp4" | "udp6";
amPm?: boolean;
}| Option | Default | Description |
|---|---|---|
timeoutMs |
3000 |
Number of milliseconds before the request rejects. Must be greater than 0. |
version |
4 |
NTP version sent in the request packet. Supports 3 or 4. |
socketType |
"udp4" |
UDP socket family. Supports "udp4" or "udp6". |
amPm |
false |
When true, returns UTC time as hh:mm:ss AM/PM instead of a Date. |
getNtpTime rejects when the request cannot complete. Known error cases
include:
- Invalid port:
Invalid NTP port: <port> - Invalid timeout:
Invalid NTP timeout: <timeoutMs> - Timeout:
NTP request timed out after <timeoutMs>ms - Short response:
Invalid NTP response: expected at least 48 bytes - Timestamp before Unix epoch:
Invalid NTP response: transmit timestamp is before Unix epoch - Socket or network errors from Node's UDP socket
try {
const date = await getNtpTime("time.google.com", 123, { timeoutMs: 1000 });
console.log(date.toISOString());
} catch (error) {
console.error(error instanceof Error ? error.message : error);
}The root library cannot run directly in the browser because browsers do not expose UDP sockets.
The frontend/ directory contains a Vite/React demo app. It uses a local Node
HTTP API that calls the root cue-ntp library, then displays the synced UTC
clock in the browser.
Run the demo:
cd frontend
npm run dev:allThe API defaults to http://127.0.0.1:4174. Vite prints the frontend URL in the
terminal.
The demo lets you set the host, port, timeout, NTP version, socket type, AM/PM output, and auto-resync behavior.
Install dependencies:
npm installUseful commands:
npm run typecheck
npm test
npm run build
npm run validatenpm run typecheckruns TypeScript without emitting files.npm testruns the Vitest suite insrc/**/*.test.ts.npm run buildbuilds ESM, CommonJS, declarations, and sourcemaps withtsup.npm run validateruns type checking and tests.
Preview package contents:
npm run pack:dryCreate a local package tarball:
npm run pack:localpack:local runs the package prepack script first, which validates and builds
the library before creating the .tgz file.
MIT