Building the free tools on Polyatic meant writing a lot of small, careful, pure functions — great-circle distance, a NOAA sunrise calculation, a Köppen climate classifier, an RFC 4180 CSV parser. None of them belonged locked inside a web page. So I pulled the logic out, gave each one tests and a focused API, and published the lot: twenty packages — nineteen under the @verifyhash npm scope, plus the polyatic-extension logic layer. Every single one has zero runtime dependencies.

🧱 What “Zero-Dependency” Buys You

That constraint is not an aesthetic. It is the whole design brief:

  • No supply chain to audit. There are no transitive packages that can be typosquatted, hijacked, or quietly abandoned. What you npm install is the entire tree.

  • Tiny and offline. Each install is a handful of files. Nothing phones home, nothing needs network at runtime, and they work the same in a browser, a serverless function, or an air-gapped box.

  • Actually readable. A library small enough to have no dependencies is usually small enough to read end-to-end before you trust it — which is the point.

🗺️ Geospatial & Astronomy

  • @verifyhash/geo-distance — haversine and WGS-84 ellipsoidal (Vincenty) distance, initial/final bearing, destination point, and midpoint.

  • @verifyhash/solar-calc — the NOAA solar algorithm: sunrise, sunset, solar noon, day length, elevation, azimuth, civil twilight, and golden hour.

  • @verifyhash/sky-planner — an offline night planner: solar and moon events plus a moonless-dark stargazing score for any lat/lon/date.

  • @verifyhash/sun-site-planner — mask-aware hours of direct sun, for solar siting, gardening, and real-estate sun checks.

  • @verifyhash/moon-phase — lunar phase angle, illuminated fraction, synodic age, phase name, and Brown lunation number (simplified Meeus).

🌡️ Weather & Climate

  • @verifyhash/climate-normals — heating/cooling degree-days, apparent (“feels like”) temperature, diurnal range, a continentality index, and a monthly pleasantness score.

  • @verifyhash/koppen-classifier — the Köppen–Geiger climate class from twelve monthly mean-temperature and precipitation values (hemisphere-aware).

  • @verifyhash/psychrometrics — saturation vapour pressure, dew point, relative and absolute humidity, NOAA heat index, and Stull wet-bulb temperature.

  • @verifyhash/wbgt-heat-stress — NWS heat index, Environment Canada humidex, and a Wet-Bulb Globe Temperature approximation with risk flags.

  • @verifyhash/uv-index — a clear-sky UV-index estimator with WHO exposure category and burn-time guidance.

  • @verifyhash/wind-scale — wind-speed conversions plus Beaufort, Saffir-Simpson, and the official 2001 NWS wind-chill formula.

  • @verifyhash/air-quality-index — the US EPA AQI for PM2.5, PM10, O3, CO, SO2, and NO2.

🧰 Data & Dev Utilities

  • @verifyhash/csv-lite — an RFC 4180 CSV parser and stringifier: quoted fields, embedded delimiters and newlines, doubled-quote escapes, header-object mode.

  • @verifyhash/ip-cidr — IPv4 (and basic IPv6) CIDR math: network, broadcast, first/last host, host count, ip↔integer, and containment.

  • @verifyhash/semver-lite — SemVer 2.0.0 parse, precedence compare, and a documented practical subset of npm-style range matching.

  • @verifyhash/iso-duration — ISO 8601 duration parse, format, calendar-correct date arithmetic, and English humanize.

  • @verifyhash/human-time — relative time (“5 minutes ago”, “in 3 days”) plus compact 2h30m ↔ ms duration format/parse.

  • @verifyhash/slugify-lite — string-to-URL-slug with accent transliteration via a pinned in-repo map, custom separators, and word-boundary truncation.

  • @verifyhash/bytesize — a byte-size humanizer and parser with round-trippable decimal (SI) and binary (IEC) formatting.

And rounding out the twenty, polyatic-extension — an MV3 browser-extension shell wrapped around a framework-free, DOM-free logic layer (JSON, JWT, QR, color) ported straight from the Polyatic tools.

🧪 How They’re Built

Every package started as production code behind a tool people already use, so the behaviour is exercised before it is ever published. Each ships with its own unit tests, a single-purpose API, and no build-time magic — the source you read on GitHub is the source that runs. Because there are no dependencies, there is no node_modules archaeology when something breaks: the bug is always in the one file you are looking at.

📦 Where to Get Them

The whole collection lives on GitHub at github.com/verifyhash/libs, and the packages are published under the @verifyhash organisation on npm. Grab one by name — npm install @verifyhash/csv-lite, or the same scope plus any other name in the lists above, such as npm install @verifyhash/moon-phase. No peer deps, no post-install scripts, nothing else pulled in behind it.

🧪 One of Them, Doing Its Job

The csv-lite bullet above claims four things: quoted fields, embedded delimiters and newlines, doubled-quote escapes, and header-object mode. Here are all four in one file you can run. This demo is ours, written for this post to exercise exactly those four behaviours and nothing else — it is not part of the package, whose own unit tests live beside its source:

// demo.js — after: npm install @verifyhash/csv-lite
const { parse, stringify } = require('@verifyhash/csv-lite');

// Input that defeats a naive split(','): a comma inside a quoted field,
// a doubled "" escape, and one record spanning two physical lines.
const csv = [
  'sku,name,notes',
  'A-1,"Widget, large","6"" shaft"',
  'B-2,"Bracket","fits A-1',
  'and A-3"'
].join('\n');

const rows = parse(csv, { header: true }); // header-object mode

console.log(rows.length);                   // 2
console.log(rows[0].name);                  // Widget, large
console.log(rows[0].notes);                 // 6" shaft
console.log(JSON.stringify(rows[1].notes)); // "fits A-1\nand A-3"

// ...and back out, re-quoting only the fields that need it:
console.log(stringify([
  ['sku', 'name', 'notes'],
  ['A-1', rows[0].name, rows[0].notes]
]));
// sku,name,notes
// A-1,"Widget, large","6"" shaft"

Four physical lines of input, two records out, and the round trip lands byte-for-byte back on the quoting it started with. The comments are the actual output. And after that install, node_modules contains exactly one directory.

← Back to all posts

Follow new posts by RSS: paste dankdev.com/feed.xml into any feed reader. It is a plain XML file — no signup, no email address, no account. Posts land there the same day they go up, and there is nothing to unsubscribe from later.

Back to the top