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

@verifyhash/wbgt-heat-stress

v0.1.0

Published

Zero-dependency heat-stress indices: NWS heat index, Environment Canada humidex, and a Wet-Bulb Globe Temperature (WBGT) approximation with risk flags.

Readme

wbgt-heat-stress

TODO (owner): pick the final npm name/scope before publishing. The npm package name is not finalized. package.json keeps the working slug wbgt-heat-stress as a placeholder — replace it (and the install line below) with the real published name/scope before any npm publish. Graduation to npm is a needs-human decision, not something this project does.

A tiny, zero-dependency Node library for the three most-used heat-stress indices, each returned with a plain-language risk category:

  • heatIndex(tempC, relHumidityPct) — the US National Weather Service "feels-like" apparent temperature (Rothfusz regression).
  • humidex(tempC, dewpointC) — Environment Canada's humidex comfort index.
  • wbgt(tempC, relHumidityPct, opts) — a Wet-Bulb Globe Temperature approximation with the white/green/yellow/red/black flag band.

Every export is a pure function: no I/O, no network, no daemon, no dependencies, and no mutation of its arguments. Same inputs → same output. Units are Celsius, percent RH, and (for outdoor WBGT) m/s wind and W/m² solar.

Who it's for

  • Occupational safety — flag heat-stress risk for outdoor/industrial crews against the WBGT flag conditions used by OSHA guidance and the US military.
  • Sports & athletics — apply the American College of Sports Medicine WBGT activity bands for training and event go/no-go decisions.
  • Weather & wellness apps — show an honest "feels like" number (heat index or humidex) without pulling in a heavy scientific package or calling an API.

If you already have a psychrometrics library, this one is complementary: it focuses on the stress indices and their risk bands, not on general moist-air math.

Install / use

Zero dependencies — vendor the folder or (after the owner finalizes the name) npm install <final-name>.

const { heatIndex, humidex, wbgt, wbgtFlag } = require('wbgt-heat-stress');

heatIndex(32.22, 70);
// { heatIndexF: 105.9, heatIndexC: 41.1, risk: 'danger' }

humidex(30, 15);
// { humidex: 33.97, risk: 'some discomfort' }

wbgt(30, 50);
// { wbgtC: 29.26, flag: 'green', mode: 'indoor' }

wbgt(30, 50, { solarWm2: 900, windMs: 1.5 });
// { wbgtC: ~31.0, flag: 'yellow', mode: 'outdoor' }

wbgtFlag(31.5); // 'red'  — band a WBGT you measured elsewhere

Running the tests

One command, no framework, no dependencies:

node test/index.test.js

It exits 0 on success and non-zero on any failure. The suite checks fixtures at published reference points — a NWS heat-index table cell, an Environment Canada humidex example, and every WBGT flag-band boundary — each within a stated tolerance, plus the input guards.

The formulas (and their sources)

Heat index — NWS/NOAA Rothfusz regression

Apparent temperature from air temperature and relative humidity. The NWS first evaluates Steadman's simple formula; if that value is below 80 °F (26.7 °C) the Rothfusz regression does not apply and the simple value is used (the documented low-temperature fallback — below ~80 °F the heat index is essentially the air temperature). Otherwise the full Rothfusz polynomial runs, with the low-humidity (RH < 13 %) and high-humidity (RH > 85 %) corrections. This is the exact method behind the published NWS heat-index chart and is accurate to about ±1.3 °F. Source: Rothfusz, L.P. (1990), NWS Technical Attachment SR 90-23; Steadman, R.G. (1979).

Risk bands (NWS, °F): none < 80, caution 80–90, extreme caution 90–103, danger 103–124, extreme danger ≥ 124.

Humidex — Environment Canada

humidex = Tair + 0.5555 * (e - 10)
e = 6.11 * exp(5417.7530 * (1/273.16 - 1/(Tdew + 273.15)))   [hPa]

Humidex is a unitless comfort index reported on the Celsius scale. When the dew point implies dry air (e ≤ 10 hPa) humidex would fall below the air temperature; Environment Canada does not report that, so the value is clamped to the air temperature. Source: Masterton, J.M. & Richardson, F.A. (1979), Environment Canada.

Comfort bands (°C-scale): none < 30, some discomfort 30–39, great discomfort 40–45, dangerous ≥ 46.

WBGT — an APPROXIMATION (read this carefully)

True WBGT cannot be computed from air temperature and humidity alone. The real index is WBGT = 0.7·Tnwb + 0.2·Tg + 0.1·Ta, where Tg is the temperature of a 150 mm matte-black globe in the actual sun/wind and Tnwb is a naturally ventilated wet-bulb — both require physical sensors. This library does not pretend to that accuracy. It provides two documented approximations:

Indoor / shaded (default). The Australian Bureau of Meteorology simplified regression, valid where there is no direct solar load (indoors, or fully shaded):

WBGT = 0.567 * Ta + 0.393 * e + 3.94
e    = (RH/100) * 6.105 * exp(17.27*Ta/(237.7 + Ta))   [hPa]

This is the standard substitute when no globe sensor is available and is what many heat-safety apps display for indoor/shaded conditions.

Outdoor (when you pass opts.solarWm2). The shade estimate plus a coarse solar-load term — direct sun raises the globe temperature and hence WBGT, while wind ventilates the globe and lowers it:

dSolar = 3.2 * (solarWm2 / 1000) / sqrt(1 + windMs)   [°C], capped at 4 °C

so ~1000 W/m² midday sun in light wind adds a few °C, tapering with wind.

Honest limits.

  • The outdoor dSolar term is a rough heuristic, not a validated model. It is tuned to give plausible magnitudes, not sensor-grade accuracy. Do not use outdoor mode as the sole basis for a real occupational go/no-go decision in the sun — measure with a black-globe WBGT meter for that.
  • Even the indoor ABM regression carries its own scatter (order ~±1 °C) versus instrumented readings and was fit for typical outdoor screen conditions.
  • Humidity must be a real measurement; a bad RH propagates directly into WBGT.
  • This library computes numbers and risk bands only. It is not a substitute for an employer's heat-illness prevention program or medical judgement.

Flag bands (US military / American College of Sports Medicine), °C converted from the canonical °F cut-points:

| Flag | WBGT (°C) | WBGT (°F) | Meaning | |--------|-------------|-------------|----------------------------------| | white | < 27.8 | < 82.0 | low risk | | green | 27.8 – 29.3 | 82.0 – 84.9 | use discretion, hydrate | | yellow | 29.4 – 31.0 | 85.0 – 87.9 | active caution; limit exertion | | red | 31.1 – 32.1 | 88.0 – 89.9 | high risk; curtail hard activity | | black | ≥ 32.2 | ≥ 90.0 | extreme; cancel/relocate |

wbgtFlag(wbgtC) is exported separately so you can band a WBGT you obtained from a real sensor.

License

MIT — see LICENSE. (Copyright holder is a placeholder pending owner sign-off.)