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

@luwiostack/country

v0.1.0

Published

Typed ISO 3166 country data for React — countries, borders, dialing codes, currencies and spoken languages, with a `<Country>` provider and `useCountry` hook.

Readme

@luwiostack/country

Typed ISO 3166 country data for JavaScript — countries, land borders, dialing codes, currencies and the languages spoken in each. A small, immutable domain model; framework-agnostic (no React required). Continents live in their own package, @luwiostack/continent — each country carries its continent_code.

Part of Luwio — standalone, with no dependency on any other @luwiostack/* package. It pairs well with them (notably @luwiostack/language and @luwiostack/locale), but the reverse: they depend on country, reading its plain code fields, not the other way around.

Install

npm install @luwiostack/country

Usage

import { Country, Countries } from '@luwiostack/country'

const be = Country.new({ code: 'BE' }) // ISO 3166-1 alpha-2
be.machine_name         // 'belgium' — stable, translation-safe key (no display name is exposed)
be.code                 // 'BE'
be.alpha3               // 'BEL'
be.numeric              // '056'
be.dialing_code         // '+32'
be.currency_code        // 'EUR'
be.continent_code       // 'EU'  (resolve the object via @luwiostack/continent)
be.timezone_names       // ['Europe/Brussels']  (resolve DST-aware Timezone objects via @luwiostack/timezone)
be.language_codes       // ['nl', 'fr', 'de']  (resolve Language objects via @luwiostack/language)

be.borders().toArray().map((c) => c.code)    // ['FR', 'DE', 'LU', 'NL']

// Country only carries the plain codes — resolve the rich objects with each sibling
// package's `.of()`, without @luwiostack/country depending on any of them:
import { Currency } from '@luwiostack/currency'
import { Languages } from '@luwiostack/language'
import { Timezones } from '@luwiostack/timezone'

Currency.of(be)?.symbol                              // '€'  (or null, e.g. Antarctica)
Timezones.of(be).toArray().map((t) => t.name)        // ['Europe/Brussels']
Languages.of(be).toArray().map((l) => l.machine_name) // ['dutch', 'french', 'german']

// Same new(), with a format for alpha-3 or numeric:
Country.new({ code: 'BEL', format: 'alpha3' }).code // 'BE'

// Collections:
Countries.benelux().toArray().map((c) => c.code) // ['BE', 'NL', 'LU']
Countries.eu().size                 // 27  — also eurozone(), schengen(), nordics(),
                                    //        baltics(), visegrad(), g7(), asean()

// Countries is an immutable, alpha-3-deduplicated collection — iterable, with the usual helpers:
for (const c of Countries.benelux()) c.code   // 'BE', 'NL', 'LU'
Countries.benelux().has(be)                    // true
Countries.benelux().map((c) => c.code)         // ['BE', 'NL', 'LU']
Countries.benelux().filter((c) => c.code !== 'LU').size // 2
Countries.empty().isEmpty()                    // true

An unknown code throws — Country.new({ code: 'ZZ' }) → Error: Unknown country: ZZ.

A country with no official currency (e.g. Antarctica) exposes currency_code === NO_CURRENCY_CODE ('NONE') and Currency.of(country) returns null — the empty string is never used, so Countries.usingCurrency({ code: '' }) is an empty collection.

API surface

  • Domain: Country (.new, .tryNew), Countries
  • Utils: toMachineName
  • Types: ICountry, ICountries, CountryCodeFormat, NO_CURRENCY_CODE

Continents moved to @luwiostack/continent — Continent, Continents, CONTINENT_MAP, IContinent. Go from a country to its continent with Continent.of(country).

Data

The bundled ISO 3166 dataset is generated from @luwiostack/iso-data (the monorepo's source of truth) and ships inside this package — nothing is fetched or read at runtime. Spoken languages are stored as ISO 639-1 codes and resolved to Language objects via @luwiostack/language.

Flags

Ready-to-use flag SVGs ship in this package's flags/ folder, one file per country named by its lowercase alpha-2 code (be.svg, nl.svg, us.svg, …) — matching country.alpha2.toLowerCase(). Like the translation catalogs, they're excluded from the published bundle (files: ["dist"]), so they add nothing to an install: download the ones you need from the docs site, host them on your own CDN, and build the URL yourself:

const flagUrl = (country: ICountry) =>
  `https://cdn.example.com/flags/${country.alpha2.toLowerCase()}.svg`

See flags/README.md for the source and licensing note.