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

countrycheck

v0.1.0

Published

Offline country point lookup: 323 KB global dataset, microsecond answers with confidence, built on the Trifold T3 triangular DGGS

Readme

countrycheck — offline country lookup

This is created as Trifold application (also test and demonstration)

Which country is this lat/long point in? gets answered anywhere on Earth in ~1–13 µs, fully offline, from a small 323 KB bundled dataset — with a confidence value for every answer. Works with Python and JavaScript. Country polygons are extended with coastal waters, so points slightly offshore still resolve to the nearest coastal country; open ocean returns "no country".

Install: pip install countrycheck / npm install countrycheck (or use straight from a repo checkout, as below).

from countrycheck import CountryCheck   # installed; from a checkout, first:
                                        # import sys; sys.path.insert(0, "countrycheck/python")

cc = CountryCheck()
cc.country(24.7536, 59.4370)          # 'EST'   (lon, lat — Tallinn)
cc.check(-0.1276, 51.5072)
# CountryResult(country='GBR', iso2='GB', name='United Kingdom', kind='country',
#               confidence=1.0, share=1.0, cell='TFA95BM', refined=False)
import { CountryCheck } from "./countrycheck/js/countrycheck.mjs";
const cc = await CountryCheck.fromFile();          // NodeJs takes bundled data directly
// OR:
const cc = await CountryCheck.fromUrl("/data/countries_L10.tfcs"); // browser needs to load data file online
cc.country(24.7536, 59.437);          // 'EST'
cc.check(-0.1276, 51.5072);
// { country: 'GBR', iso2: 'GB', name: 'United Kingdom', kind: 'country',
//   confidence: 1, share: 1, cell: 'TFA95BM', refined: false }

How it works

The Trifold level-10 grid (~7 km triangles, 21M cells globally) is classified against country polygons extended with coastal waters (256 countries and territories, including X-coded ones like Kosovo or the Caspian Sea that have no ISO code). The borders come from the timezone-boundary-builder "with oceans" polygons (OSM-derived, so they follow the true line and already reach into nearby territorial water); GADM level-0 supplies only the country identity and ISO codes, joined by maximum land overlap. (That timezone source carries occasional antenna artifacts — a vertex spiking off the border and back; scripts/despike_countries.py removes them before the grid build, touching 0.02% of vertices with no measurable area change.) 6.90M cells belong to some country, of which 195,473 are border cells (crossed by a country/country or country/water edge) and the rest are wholly interior. Because Trifold addresses sort hierarchically, every cell at any level maps to a contiguous range in the canonical level-10 index space (face·4¹⁰ + path), so the entire classification collapses to 222,855 run-length intervals — 324 KB compressed, including the country table and, for every border cell, the best country call with a 4-bit area share.

A lookup is: locate the point's level-10 triangle (pure float math, no dependencies), then binary-search the runs.

| answer kind | meaning | country | confidence | |---|---|---|---| | country | cell wholly inside one country | that country | 1.0 | | none | cell absent from dataset (international waters) | None | 1.0 | | border | mixed cell | best call (may be None) | call's area share | | border + refined | decided by exact polygon test | exact | 0.99 |

Measured accuracy (100,000 uniform random points vs. exact polygon containment in the source dataset): 99.83% agreement overall; country and none answers correct; all residual error lives in border answers, which self-report their lower confidence. With the border refinement loaded, agreement is 99.995% (5 points in 100,000, all coastal water claimed by two countries where the tie-break differs).

Independent accuracy — against 57,501 real airports (OurAirports, each tagged with an ISO country code), countrycheck places 99.50% in the right country with the bundled data and 99.68% with the refinement. Interior-country answers are 99.91% right; the refinement works only on the 729 airports that fall in a border cell, lifting those from 80.66% to 95.20%. The remaining disagreements are mostly genuine source differences (disputed/border territory the sources assign differently, dependencies coded to a parent state, offshore or placeholder coordinates). Reproduce with scripts/accuracy_countrycheck_airports.py.

Caveats inherited from the source data: coastal waters come from the timezone "with oceans" polygons (an operational maritime extent, not legal EEZ); disputed/border territory follows whatever the two sources encode (e.g. Crimea, Western Sahara, the Korean DMZ); lakes belong to their surrounding country except the Caspian Sea, which is its own XCA entry.

Optional border refinement

For applications that need exact borders, a second dataset (borders_L10.tfcr, 19.2 MB) stores the source country polygons clipped to every border cell, quantized to a cell-local 16-bit grid (~0.1 m) with delta-varint rings, one zone per country present in the cell. When loaded, border answers switch from the bulk best-call guess to an exact point-in-polygon test — country/country land borders and the coastline both resolve exactly (~13 µs per refined lookup, Python):

cc = CountryCheck(refine_path="countrycheck/data/borders_L10.tfcr")
await cc.loadRefinement("countrycheck/data/borders_L10.tfcr");

Only border cells pay the polygon-test cost; interior and open-water answers are unaffected (they are already exact).

Command-line one-off checks (uses refinement automatically when the file is present):

$ python countrycheck/python/countrycheck.py 24.7536 59.4370
EST  iso2=EE  name='Estonia'  kind=country  confidence=1.000  share=1.0  cell=TFAVKGR  refined=False

Performance

| operation | speed | |---|---| | Python scalar country | ~13 µs/point (79k/s) | | Python batch country_batch (numpy) | ~3 µs/point | | JavaScript country (Node) | ~0.6 µs/point (1.6M/s) | | dataset load | ~40–75 ms |

The Python library is dependency-free (stdlib only); country_batch optionally uses numpy + the trifold SDK. The JS library is a single ES module, works with browser + Node.

Benchmark vs SQL spatial engines

Same job for every engine: assign a country (gid_0) to 100,000 sphere-uniform random points against the same country polygons. Median of seven warm runs on an Apple M5 Pro (June 2026). Refined countrycheck reproduced exact point-in-polygon containment on 99.995% of the points (5 of 100,000, all coastal-overlap tie-breaks; base 99.83%) while running far faster:

| engine | batch | points/s | vs Trifold | |---|---:|---:|---:| | Trifold base | 0.221 s | 452,594 | 1× | | Trifold + refinement | 0.234 s | 428,151 | 1× | | PostGIS 3.6.3 | 1.694 s | 59,043 | 7.7× slower | | DuckDB 1.5.3 Spatial | 21.499 s | 4,651 | 97× slower |

Called one point at a time, Trifold answered ~88,000 lookups/s vs 2,261 (DuckDB) and 1,265 (PostGIS). DuckDB and PostGIS returned byte-identical answers. Full methodology, the singular numbers, dataset manifest, the airport accuracy test and the BigQuery procedure are in countrycheck_benchmark.md; the scripts are scripts/benchmark_countrycheck.py and scripts/benchmark_countrycheck_sql_scalar.py.

Files

build.py               TFCS + TFCR builder: countries_coastal.geojson -> data/
python/                countrycheck.py (public API) · _fastloc.py (point location)
js/countrycheck.mjs    the JS library (same data, same answers)
data/                  countries_L10.tfcs (bundled) · borders_L10.tfcr (optional)
tests/                 pytest + node:test suites, shared fixture (points.json)

Rebuild from the source polygons:

python countrycheck/build.py               # needs osm-vector/countries_coastal.geojson
python countrycheck/tests/make_fixture.py  # refresh cross-language fixture
pytest countrycheck/tests/ && node --test countrycheck/tests/test_countrycheck.mjs

Format notes

Custom data format is used to ensure compactness.

  • TFCS (country runs): 20-byte header + zlib stream of a country table (code/iso2/name strings), then varint(gap), varint(length<<1 | border) per run — interior runs carry varint(country_id), border runs are followed (in a separate block) by a per-cell best call (varint(0=none | country_id+1)) and a 4-bit area share.

  • TFCR (refinement): 12-byte header + zlib stream of varint(Δindex), varint(n_zones) per border cell, each zone a country id plus quantized zigzag-delta rings combined by the even-odd rule (zero rings = whole cell). Both formats are level-agnostic (the level lives in the header), so the same tooling can serve an L8 or L12 variant.

Roadmap

  • Level-12 (~1.8 km trifolds) variant for higher-precision use.
  • Timezone detection from the same source data (tzids are already in the per-country properties; cells would map to tzid instead of country id).
  • Custom polygon identities — generalise the builder into a universal "polygon layer → grid identity" indexer for any non-overlapping layer (counties, ZIP/postal areas, admin units, electoral or sales districts, timezones — the item above is just one instance). This is mostly build.py parameterised: take an arbitrary id field instead of gid_0/iso2/name, drop the country-specific source prep (coastal/territorial-water extension, GADM↔timezone reconciliation), and choose the level per layer (finer for dense small polygons). The cell runs, the mixed-cell best-call + area share, and the TFCR exact-border refinement are already identity-agnostic; only the 65,535-identity ceiling (a u16 header count + the len(countries) > 0xFFFF guard — payload ids are already varints) needs widening to u32 for very large layers such as global postal codes.
  • Published packages: pip install countrycheck and npm install countrycheck; the core SDK is pip/npm install t3grid.