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

humane-ts

v0.1.0

Published

File sizes the way macOS Finder shows them, and relative dates in Rails ActionView's wording

Readme

humane-ts

TypeScript CI Release License

File sizes that read exactly the way macOS Finder shows them ("4.1 MB", "226 KB"), and relative dates in Rails ActionView's wording ("about 3 hours ago", "in 3 minutes"), for TypeScript and JavaScript. No dependencies.

import { humanSize, timeAgo, distanceInTime } from 'humane-ts'

humanSize(225_935) // "226 KB"

const mtime = new Date(Date.now() - 180_000)
timeAgo(mtime) // "3 minutes ago" -- relative to the real clock

const now = new Date()
distanceInTime(mtime, now) // "3 minutes ago" -- explicit relativeTo, for tests

Install

npm install humane-ts

To install the latest main instead, straight from GitHub (built on install):

npm install github:woodie/humane-ts

ES module only, with TypeScript types included.

File sizes

humanSize matches Foundation's ByteCountFormatter (file style), which is what macOS Finder shows, and is checked against real Finder output:

  • 1000-based units with capitalized labels: KB, MB, GB, TB, and up.
  • A fixed number of decimal places per unit -- none for KB, one for MB, two for GB and above -- with trailing zeros dropped ("2 MB", not "2.0 MB").
  • Rounds half up, and moves up a unit when rounding reaches 1000: 999,999 bytes is "1 MB", not "1000 KB".
  • Zero bytes is "Zero KB", and anything under 1000 bytes is spelled out ("1 byte", "7 bytes").
humanSize(2_579)         // "3 KB"
humanSize(4_132_383)     // "4.1 MB"
humanSize(999_999)       // "1 MB"
humanSize(5_240_000_000) // "5.24 GB"

Popular alternatives like pretty-bytes and filesize round differently ("4.13 MB", "2.58 kB") and label units in SI style (kB, B), so their output won't match what Finder shows.

distanceInTime and timeAgo

Two entry points, same naming split as ActionView's own distance_of_time_in_words/time_ago_in_words:

  • distanceInTime(at, relativeTo, options?) -- the explicit, fully-tested core. Takes both times, plus a possibly-null at, so it's what tests should call.
  • timeAgo(at, options?) -- a one-argument convenience for the common "drop into a view" case. Supplies the current time as relativeTo.

The wording follows ActionView's distance_of_time_in_words, with one difference: direction is picked for you. A past time reads "3 minutes ago" and a future one "in 3 minutes", where ActionView leaves that to the caller.

Both take the same options, with recommended defaults that already match ActionView's own -- pass none at all and you get them for free:

distanceInTime(at, relativeTo) // { approximate: true, includeSeconds: false }
timeAgo(at)                    // same defaults, relativeTo is now
  • approximate (default true): prefixes "about"/"in about" on the hour-scale buckets (1 hour, and 2..24 hours), matching ActionView's distance_of_time_in_words wording for those buckets exactly (down to its 44:30/89:30 rounding cutoffs), through the "1 day" bucket.
  • includeSeconds (default false): under 30 seconds, collapses to "less than a minute ago"/"in less than a minute" instead of an exact second count. Matches ActionView's include_seconds default.
  • whenNil (default ""): if at is null or undefined, distanceInTime returns this string without formatting -- for a scan, download, or other record that doesn't have a timestamp yet.
distanceInTime(at, relativeTo, { approximate: false }) // "15 hours ago", not "about 15 hours ago"
distanceInTime(null, new Date(), { whenNil: 'an unknown time' }) // "an unknown time"

date-fns's formatDistance uses the same ActionView wording, and is the better choice if you already depend on it or need months and years. It has no way to drop "about", phrases seconds differently ("half a minute"), and continues past days into "about 1 month" and "about 2 years".

Scope

Finder's byte-count style, and a numeric (non-calendar-aware) relative time style through the "1 day" bucket -- that's the whole surface area today. Alternate size units/styles and a named style ("yesterday", calendar-boundary-aware) aren't implemented -- contributions welcome.

Development

Requires Node 22.13 or later for the dev tools; the published library itself runs on Node 18 and any modern browser.

npm install
make test
make check

make test prints the full nested describe/context/it output from Vitest; make check runs lint, the type check and the tests together, quietly unless something fails.