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

@verifyhash/human-time

v0.1.0

Published

Zero-dependency human-readable relative time ('5 minutes ago', 'in 3 days') plus compact ms-style duration format/parse ('2h30m' <-> ms) for Node.js. English-only.

Readme

human-time

A tiny, zero-dependency Node.js library for two everyday time chores:

  1. Relative phrases — turn a timestamp into "5 minutes ago" or "in 3 days".
  2. Compact durations — turn milliseconds into "2h30m" and back again.

No install step, no node_modules, no network, no servers. One file: src/index.js. Node 12+.

English only. Output is fixed English. There is no locale/pluralization layer here on purpose — if you need localized phrasing, reach for Intl.RelativeTimeFormat or a full i18n library. This module optimizes for being small, dependency-free, and predictable.

Who it's for

Anyone rendering timestamps or durations in a CLI, log line, dashboard, or small web app who wants friendly output without pulling in moment, dayjs, date-fns, or ms. It is deliberately distinct from the sibling iso-duration library: iso-duration parses/formats ISO 8601 durations (PT1H30M) and does calendar-correct date arithmetic; human-time does approximate human phrasing and compact ms-style strings.

Install / use

Copy the folder in, or require it directly — there is nothing to build.

const { relative, format, parse } = require('human-time'); // main = src/index.js

API

relative(from, to?) -> string

Describes from as seen from the reference to. Both arguments accept a Date or epoch-milliseconds (a number). to defaults to Date.now() when omitted — so the common one-argument call just works:

relative(Date.now() - 5 * 60 * 1000);   // "5 minutes ago"
relative(Date.now() + 90 * 60 * 1000);  // "in 2 hours"
relative(new Date('2000-01-01'), new Date('2000-01-01')); // "just now"

Direction is chosen so single-argument calls read naturally: when from is earlier than to you get past tense ("N ... ago"); when from is later you get future tense ("in N ..."). Anything under one second, in either direction, is "just now".

The threshold ladder (each band rounds to its nearest whole unit):

| Gap | Output examples | | ----------------------- | ---------------------------- | | < 1s | just now | | 1s< 1m | 1 second ago59 seconds ago | | 1m< 1h | 5 minutes ago, in 12 minutes | | 1h< 1d | 3 hours ago | | 1d< 1w | 3 days ago | | 1w< 1 month | 2 weeks ago | | 1 month< 1 year | 3 months ago | | >= 1 year | 2 years ago, in 5 years |

Honest limits: months and years use average Gregorian lengths (30.436875 and 365.2425 days), so "3 months ago" is approximate, never calendar-exact — if you need "exactly 3 calendar months", use date arithmetic (e.g. the iso-duration sibling), not this. Values sit in a single band and round, so a 25-hour gap reads "1 day ago", not "1 day 1 hour ago".

format(ms) -> string

Compact, ms-package-style duration string. Emits every non-zero component from days down to milliseconds, largest first, so it round-trips through parse:

format(9_000_000);          // "2h30m"
format(24*3600*1000 + 4*3600*1000); // "1d4h"
format(45_000);             // "45s"
format(500);                // "500ms"
format(1_500);              // "1s500ms"
format(0);                  // "0ms"
format(-5_000);             // "-5s"

Fractional input is rounded to the nearest millisecond. Non-finite input throws.

parse(str) -> number (milliseconds)

The inverse of format. Case-insensitive and tolerant of spacing. Understands d, h, m, s, and ms, plus an optional leading -/+:

parse('2h30m');    // 9000000
parse('2H 30M');   // 9000000  (case + spacing don't matter)
parse('1d4h');     // 100800000
parse('500ms');    // 500
parse('-1m30s');   // -90000
parse('1.5h');     // 5400000  (fractional units allowed)

Empty, garbage, or unknown-unit input throws rather than silently returning 0, so typos surface loudly.

units

The unit sizes in milliseconds are exposed as units.SECOND / MINUTE / HOUR / DAY / WEEK / MONTH / YEAR for callers who want the same constants.

Running the tests

One command, no dependencies:

node test/index.test.js

It exits 0 when all assertions pass (and prints a pass/fail count). The suite covers past and future phrasing, every threshold band, formatparse round-trips, sub-second inputs, negative/zero durations, and invalid-input error handling.

License

MIT — see LICENSE.