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

anylocale

v1.0.1

Published

Small locale-info reader — when you need to know text direction, first day of week, weekend, calendars and time zones for any locale, straight from native Intl.

Readme


One export. Real CLDR answers. Any locale. ~1kb gzip. Zero dependencies.

Everyone hardcodes this and everyone gets it wrong. Your runtime already ships the correct table for 200+ locales — anylocale is the thin reader. No language lists, no data files, no config.

import { anylocale } from "anylocale";

anylocale("ar-EG").direction;  // "rtl"
anylocale("en-GB").weekStart;  // 1 — Monday
anylocale("en-US").weekStart;  // 7 — Sunday, same language
anylocale("fa-IR").weekend;    // [5] — Friday only, not a pair
anylocale("ar-EG").timeZones;  // ["Africa/Cairo"]

install

npm install anylocale

usage

anylocale(tag);
anylocale([tag, fallback]);

tag is a BCP 47 locale tag, or an array used as a fallback chain — the first tag the runtime actually has data for wins.

Fields are computed on access, so reading direction never asks the runtime for calendars or time zones. The record still spreads and serialises like a plain object.

const { direction, weekStart } = anylocale(navigator.language);

JSON.stringify(anylocale("en-US"));
// {"tag":"en-US","direction":"ltr","weekStart":7,…}

anylocale.supported reports whether the runtime exposes Intl Locale Info at all — see compatibility.


recipes

Copy, paste, move on.

// Set document direction without a hand-kept RTL language list
document.documentElement.dir = anylocale(userLocale).direction;

// …or in React
<html lang={locale} dir={anylocale(locale).direction}>

// Order the columns of a date picker
const start = anylocale(locale).weekStart;              // 1–7, ISO
const days = Array.from({ length: 7 }, (_, i) => ((start - 1 + i) % 7) + 1);

// Highlight weekend cells — not always Saturday and Sunday
const weekend = new Set(anylocale(locale).weekend);
const isWeekend = (isoDay: number) => weekend.has(isoDay);

// 12- or 24-hour clock, per the locale rather than per the language
const use12h = anylocale(locale).hourCycles[0] === "h12";

// Offer the calendar the region actually uses
anylocale("fa-IR").calendars[0];   // "persian"
anylocale("th-TH").calendars[0];   // "buddhist"

// Suggest a default time zone from the user's locale
anylocale("ar-EG").timeZones[0];   // "Africa/Cairo"

// Degrade gracefully on runtimes without Intl Locale Info
const dir = anylocale.supported ? anylocale(locale).direction : "ltr";

anylocale is pure and synchronous — no clock, no state — so server and client render identically.


fields

| Field | Type | What it is | | --- | --- | --- | | tag | string | the canonical tag that was resolved — "en-us""en-US" | | direction | "ltr" \| "rtl" | text direction of the locale's script | | weekStart | 17 | first day of the week, ISO numbering | | weekend | number[] | days counted as the weekend, ISO numbering | | minimalDays | number | days of a week that must fall in a year for it to be that year's first week | | calendars | string[] | usable calendars, preferred first | | timeZones | string[] | IANA zones for the region; empty for language-only tags | | hourCycles | string[] | "h12", "h23", … preferred first | | numberingSystems | string[] | "latn", "arab", … preferred first |

weekStart and weekend are ISO: 1 is Monday, 7 is Sunday. JavaScript's Date.prototype.getDay() is not — it returns 0 for Sunday. Convert with iso % 7.

Every field, with the surprising cases


what people get wrong

Straight from the data, not from opinion:

| | en-US | en-GB | ar-EG | he-IL | fa-IR | | --- | --- | --- | --- | --- | --- | | direction | ltr | ltr | rtl | rtl | rtl | | week starts | Sun | Mon | Sat | Sun | Sat | | weekend | Sat, Sun | Sat, Sun | Fri, Sat | Fri, Sat | Fri | | clock | h12 | h23 | h12 | h23 | h23 | | digits | latn | latn | arab | latn | arabext |

  • Same language, different week. en-US starts Sunday, en-GB Monday. A table keyed on language is wrong for half the English-speaking world.
  • The weekend is not always a pair. fa-IR has one day.
  • RTL does not imply Arabic digits. he-IL is right-to-left and uses Latin numerals.
  • Nor does language decide the clock. en-US is 12-hour, en-GB is 24.

locales

Any valid BCP 47 tag. A fallback chain resolves to the first tag the runtime has data for, not merely the first that parses — "xx-Nope" is well-formed BCP 47 and would otherwise win.

anylocale("pt-BR").tag;                  // "pt-BR"
anylocale(["xx-Nope", "de-DE"]).tag;     // "de-DE"
anylocale("en-us").tag;                  // "en-US"  — canonicalised

If no tag in the chain has data, the first well-formed one is used and the runtime answers with its own defaults, rather than throwing.


vs the alternatives

| | anylocale | rtl-detect | hand-kept tables | | --- | :---: | :---: | :---: | | gzip | ~1kb | ~2kb | 0 (yours) | | locale data bundled | no | yes | yes | | covers | direction, week, calendars, zones, clock, digits | direction | whatever you wrote | | stays current | with the runtime's ICU | with releases | never | | dependencies | 0 | 0 | 0 |

anylocale answers how a locale behaves. For what a code is called"US""United States" — that is anyaround's job.


stability

anylocale follows semver. The public API is a single export — anylocale, with anylocale.supported on it — plus AnylocaleInfo and the exported types. It only changes shape in a major release.

Values come from the runtime's CLDR data and can shift between ICU versions, so test behaviour rather than exact arrays.


compatibility

Intl Locale Info reached Stage 4 (ES2026). It was standardised twice: first as properties (locale.weekInfo), then as methods (locale.getWeekInfo()). Engines are split — Node 22 ships only the properties, and nothing else in the family has to deal with two shapes of the same API. anylocale reads whichever it finds, so you never have to.

Because support is uneven and moving, feature-detect rather than trust a version table:

const dir = anylocale.supported ? anylocale(locale).direction : "ltr";

anylocale.supported is false on engines with neither shape, and every call throws there. The package itself runs anywhere Node 18+ runs; the data is what may be missing.

CI runs the full suite on Node 20, 22 and 24, skipping the data-dependent tests wherever the API is absent.


the any family

anylocale is part of any family — tiny, zero-dependency wrappers over native Intl, one API per package.

| | | | | --- | --- | --- | | anywhen | dates & relative time | Intl.DateTimeFormat | | anyamount | numbers, currency, units | Intl.NumberFormat | | anymany | lists | Intl.ListFormat | | anyaround | names & flags | Intl.DisplayNames | | anylong | durations | Intl.DurationFormat | | anyplural | plurals | Intl.PluralRules | | anyword | words & graphemes | Intl.Segmenter | | anylocale | locale behaviour | Intl.Locale info |

Want all of them? anyfamily is one install for the lot, and anyfamily-react wraps each as a hook with a shared locale provider.

npm install anyfamily

MIT © kirilinsky