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

slim-natural-earth

v1.0.0

Published

Strip Natural Earth admin-0 GeoJSON down to a small property set, merge in named subunits, generate polygon labels, and emit gzip/brotli copies.

Readme

slim-natural-earth

Strips Natural Earth admin-0 (country / map-subunit) GeoJSON down to a small, web-map-friendly property set, optionally merges named subunits into the country layer, generates polygon-label point features, and emits gzip + brotli copies — all from one CLI.

npx slim-natural-earth build --version-tag 5.1.2 --property-set micro
npx slim-natural-earth --help

Or install it: npm i -g slim-natural-earth, then run slim-natural-earth ....

Hardened: 2026-10-30 · d1d82c5 · gate CLOSED WITH FOLLOW-UPS

What it’s good for

Natural Earth’s admin-0 country and map-subunits GeoJSON files ship with 50+ cartographic/demographic properties per feature — more than most web maps need, and enough to noticeably bloat a bundle. This tool strips each feature down to a named property set (min or micro, or your own custom list), optionally folds a handful of named subunits (dependent territories, constituent countries, etc.) into the country layer so they render separately from their parent, generates a label point for each polygon via geojson-polygon-labels, and writes gzip/brotli copies of the results using Node’s built-in zlib (no external compression CLI).

Getting the data

This tool operates on Natural Earth’s admin-0 GeoJSON releases — it does not download or bundle them. Grab the files you need manually:

  1. Go to naturalearthdata.com and pick a scale (110m, 50m, or 10m — 50m is a common web-map choice). Under Cultural vectors, download:

    • Admin 0 – Countries (ne_<scale>_admin_0_countries.geojson)
    • Admin 0 – Map subunits (ne_<scale>_admin_0_map_subunits.geojson), only needed if you plan to use merge/--merge-subunits

    Direct download pages:

    Or pull GeoJSON straight from the mirrored source repo: https://github.com/nvkelso/natural-earth-vector/tree/master/geojson

  2. Rename the downloaded files to include a version tag and place them in an input directory (./lib by default), matching the pattern this tool expects:

    lib/ne_50m_admin_0_countries-5.1.2.geojson
    lib/ne_50m_admin_0_map_subunits-5.1.2.geojson

    The version tag (5.1.2 above) can be anything you want — it’s just carried through into the output filenames via --version-tag so you can tell releases apart. Natural Earth doesn’t stamp a version into its own filenames, so this is a convention this tool introduces, not one it reads from the download.

  3. Run slim-natural-earth build (see Usage below) pointing --input-dir at that directory.

Natural Earth data is public domain; see their terms of use (no attribution required).

Usage

slim-natural-earth has five subcommands. build runs the common pipeline end to end; the other four are the individual steps, usable on their own.

build — the full pipeline

slim-natural-earth build \
  --input-dir ./lib \
  --output-dir ./dist \
  --version-tag 5.1.2 \
  --property-set micro \
  --merge-subunits \
  --subunit-names "Greenland,Puerto Rico"
--input-dir <dir>          Directory containing the raw Natural Earth files
                            (default: ./lib)
--output-dir <dir>         Directory to write results into (default: ./dist)
--prefix <string>          Filename prefix shared by the input layers
                            (default: ne_50m_admin_0_)
--version-tag <string>     Version tag embedded in filenames (required)
--countries-name <string>  Countries layer basename (default: countries)
--subunits-name <string>   Subunits layer basename (default: map_subunits)
--property-set, -p         "min", "micro", or a comma-separated custom list
                            of field names (default: min)
--merge-subunits           Merge named subunits into the country layer
--subunit-names <list>     Comma-separated subunit "name" values to merge in
                            (required with --merge-subunits)
--labels                   Generate a polygon-labels file (default: true;
                            --no-labels to skip)
--label-method <string>    geojson-polygon-labels placement method:
                            polylabel, center, center-of-mass, center-mean,
                            center-median, centroid, point-in-polygon
                            (default: polylabel)
--label-collections        geojson-polygon-labels Multi*/GeometryCollection
                            handling: largest, explode, combine
                            (default: largest)
--compress                 Write gzip/brotli copies of the results
                            (default: true; --no-compress to skip)

--label-collections largest gives one label per feature, placed in its largest part. combine labels the outline around all the parts together, so a country with distant parts (France and French Guiana, say) gets its label in the gap between them; explode gives one label per part.

A bad --label-method, --label-collections or --property-set value is refused before anything is read or written.

Without --merge-subunits, build just slims the countries layer and writes <prefix><countries-name>-<property-set>-<version-tag>.geojson. With it, both layers are slimmed, the named subunits are folded into the country features, and the result is written as <prefix>custom-<property-set>-<version-tag>.geojson — mirroring the ne_50m_admin_0_countries-… / ne_50m_admin_0_custom-… naming split.

slim — strip properties on a single file

slim-natural-earth slim --input ./lib/ne_50m_admin_0_countries-5.1.2.geojson \
  --output ./dist/countries-min.geojson --property-set min

--property-set (-p) accepts min, micro, or a comma-separated list of your own field names, e.g. --property-set name,iso_a3,pop_est. Pass --subunit-layer when slimming a map-subunits file, so every output feature gets is_subunit: true.

merge — fold named subunits into a country layer

slim-natural-earth merge \
  --countries ./dist/countries-min.geojson \
  --subunits ./dist/subunits-min.geojson \
  --names "Greenland,Puerto Rico" \
  --output ./dist/custom-min.geojson

Matched subunit features are prepended ahead of the country features, so renderers that paint in feature order (SVG/D3, canvas, Leaflet, and features within one GL layer) draw them first, underneath the countries. To draw them on top, put the is_subunit: true features in a later layer. Name matching is case-insensitive. A name that matches no subunit prints a warning on stderr; if none of the names match, the command fails (exit 1) and writes nothing. build --merge-subunits does the same. An empty list (--names ',') is refused.

label — generate label points

slim-natural-earth label --input ./dist/custom-min.geojson \
  --output ./dist/custom-min.labels.geojson --method polylabel --collections largest

Thin wrapper around geojson-polygon-labels; see its README for the full set of --method and --collections options. --collections defaults to largest here (upstream’s default is combine; see build above for why). Polylabel runs at a precision of 0.001 coordinate units (about 100 m in degrees) rather than upstream’s 0.000001, which can exhaust memory on long, straight-sided polygons.

Input must be longitude/latitude, as RFC 7946 GeoJSON is. In projected coordinates (metres, say) 0.001 is a millimetre and the label step can hang, so input with any coordinate beyond ±360 longitude or ±90 latitude is refused. If geojson-polygon-labels writes output that does not parse (it can exit 0 after an error), the labels file is removed and the command fails. --output must be a file path, not a directory.

compress — gzip/brotli one or more files

slim-natural-earth compress --input ./dist/custom-min.geojson ./dist/custom-min.labels.geojson

Writes <file>.gz and <file>.br next to each input via Node’s built-in zlib module. Pass --no-gzip or --no-brotli to skip one (not both).

Property sets

Field names are Natural Earth’s standard admin-0 attribute schema (see the Natural Earth documentation for what each column means). Every output feature also gets an is_subunit boolean, set from context (the slim/build subunit-layer flag), regardless of which property set is chosen.

  • micro — a tiny, display-oriented set: type, name, name_long, admin, iso_a3, formal_en, continent, subregion, region_wb.

  • min — a fuller set covering identification, geometry-adjacent cartographic helper fields, and demographics: type, featurecla, scalerank, labelrank, sovereignt, sov_a3, adm0_dif, level, tlc, admin, adm0_a3, geou_dif, geounit, gu_a3, su_dif, subunit, su_a3, name, name_long, abbrev, postal, formal_en, name_ciawf, name_sort, name_alt, mapcolor7, mapcolor8, mapcolor9, mapcolor13, pop_est, pop_rank, pop_year, gdp_md, gdp_year, economy, income_grp, fips_10, iso_a2, iso_a3, iso_n3, woe_id, woe_note, adm0_iso, adm0_diff, adm0_tlc, adm0_a3_un, continent, region_un, subregion, region_wb, tiny, homepart, min_zoom, min_label, max_label, label_x, label_y, ne_id, wikidataid.

  • custom — pass any comma-separated list of field names to --property-set/-p (case-insensitive; input property keys are lower-cased before matching). Fields absent from a given feature are simply omitted from its output, not padded with null. An empty list (-p '' or -p ',') is refused.

Notes

  • A known upstream quirk, worked around internally: [email protected]’s default (--input-format=geojson) code path has a this-binding bug (this.queue(...) inside an arrow function passed to the through package) that silently drops every feature, plus separately double-nests its --output-format=geojson wrapper. This tool’s label step converts its input to newline-delimited GeoJSON (--input-format=geojsonseq) before invoking the CLI, which sidesteps both bugs — no patched dependency needed, no action required on your part. Both bugs are reported upstream with a fix (issue #30, PR #31); if the PR merges and a release follows, this workaround can be retired.

  • lib/ and dist/ are gitignored in this repo. The tool writes no .gitignore of its own, so in your own project add the directories you point --input-dir/--output-dir at, if you don’t want Natural Earth source files and generated output committed.

Exit codes

  • 0 — success, including a merge where some (not all) subunit names matched; each unmatched name is a Warning: line on stderr.
  • 1 — anything else. A usage error (unknown option, bad choice, missing required option) prints the help screen and the reason. A runtime error (missing or unreadable input, input that is not a GeoJSON FeatureCollection, an empty --property-set or name list, no subunit name matched, coordinates that are not longitude/latitude, a failed label run) prints one Error: … line.

Known limits

  • Polylabel precision is fixed at 0.001 coordinate units; there is no flag to change it. That is about 100 m for longitude/latitude data, finer than a label needs. Projected input is refused only when a coordinate is out of longitude/latitude range, so projected data near the origin gets through.
  • If a run is killed (Ctrl-C) during the label step, the temporary directory slim-natural-earth-labels-* under your system temp directory is left behind. A label step that fails on its own removes it, and the partial labels file.
  • build writes the slimmed file before the label step runs, so a label failure leaves the slimmed .geojson in the output directory without its labels or compressed copies.
  • Only the geojson-polygon-labels 2.0.1 code path is tested; the dependency range is ^2.0.1, so a later 2.x reaches you untested (see the upstream note above).
  • Not tested against real Natural Earth releases in CI (the test fixtures are synthetic) or on Windows.

Requirements

Node 18+.

License

MIT