@verifyhash/wind-scale
v0.1.0
Published
Zero-dependency wind speed conversions plus Beaufort, Saffir-Simpson, and the official 2001 NWS wind-chill formula.
Maintainers
Readme
wind-scale
TODO (owner): pick the final npm name/scope before publishing. The npm package name is not finalized by this project. Convention used here:
package.jsonkeeps the working slugwind-scaleas a placeholder — replace it (and thenpm installline below) with the real published name/scope before runningnpm publish.
Zero-dependency, pure-JavaScript wind utilities: convert speeds between the five units meteorologists actually use, and classify a wind on the three scales the public sees on forecasts — the Beaufort force scale, the Saffir-Simpson hurricane scale, and the official U.S. National Weather Service wind-chill temperature.
No dependencies, no network, no I/O. Every function is pure: given the same inputs it always returns the same value and mutates nothing. It runs anywhere Node.js runs and is trivial to vendor into a browser bundle.
Who it's for
- Weather / marine / aviation dashboards that receive wind in one unit (say METAR knots) and must display another (mph, km/h).
- Anyone turning a raw wind speed into a human label ("Force 7, near gale" or "Category 3 hurricane").
- Cold-climate apps computing the "feels-like" wind-chill temperature with the correct, current NWS formula instead of the obsolete pre-2001 one.
Install / use
It's a single file with no dependencies. Copy src/wind-scale.js into your
project or require it directly:
const { convert, beaufort, saffirSimpson, windChill } = require('./src/wind-scale.js');API
convert(value, fromUnit, toUnit) -> number
Convert a wind speed between any two of these units:
| code | unit |
|--------|------------------|
| ms | metres/second |
| kmh | kilometres/hour |
| mph | miles/hour |
| kn | knots |
| fts | feet/second |
Exact factors relative to 1 m/s:
1 m/s = 3.6 km/h = 2.2369362920544 mph = 1.9438444924406 kn = 3.280839895 ft/s.
convert(10, 'ms', 'kmh'); // 36
convert(100, 'kmh', 'mph'); // 62.137119223733...
convert(50, 'kn', 'mph'); // 57.539019...Throws TypeError if value is not a finite number and RangeError for an
unknown unit code.
beaufort(speedMs) -> { force, description, minMs, maxMs }
Classify a wind speed in metres per second on the 0–12 Beaufort scale. The
result gives the integer force, its standard WMO description, and the band's
bounds in m/s: minMs (inclusive lower bound) and maxMs (exclusive upper
bound; Infinity for Force 12). Bands are contiguous — the maxMs of one force
equals the minMs of the next.
Boundaries (m/s), Force 0 below 0.5 up to Force 12 at 32.7 and above:
| force | m/s band | description | |-------|--------------|-----------------| | 0 | < 0.5 | Calm | | 1 | 0.5–1.6 | Light air | | 2 | 1.6–3.4 | Light breeze | | 3 | 3.4–5.5 | Gentle breeze | | 4 | 5.5–8.0 | Moderate breeze | | 5 | 8.0–10.8 | Fresh breeze | | 6 | 10.8–13.9 | Strong breeze | | 7 | 13.9–17.2 | Near gale | | 8 | 17.2–20.8 | Gale | | 9 | 20.8–24.5 | Strong gale | | 10 | 24.5–28.5 | Storm | | 11 | 28.5–32.7 | Violent storm | | 12 | >= 32.7 | Hurricane force |
beaufort(9.0);
// { force: 5, description: 'Fresh breeze', minMs: 8, maxMs: 10.8 }
beaufort(40);
// { force: 12, description: 'Hurricane force', minMs: 32.7, maxMs: Infinity }If your speed is in another unit, feed it through convert first:
beaufort(convert(20, 'kn', 'ms')).
Throws TypeError for non-finite input and RangeError for negative speeds.
saffirSimpson(sustainedMph) -> { category, label }
Classify a tropical cyclone by its 1-minute sustained wind in mph. Uses the
Saffir-Simpson Hurricane Wind Scale plus the U.S. National Hurricane Center's
sub-hurricane designations. category is 'TD', 'TS', or the number 1–5.
| category | sustained mph | label |
|----------|---------------|-----------------------|
| 'TD' | < 39 | Tropical Depression |
| 'TS' | 39–73 | Tropical Storm |
| 1 | 74–95 | Category 1 Hurricane |
| 2 | 96–110 | Category 2 Hurricane |
| 3 | 111–129 | Category 3 Hurricane |
| 4 | 130–156 | Category 4 Hurricane |
| 5 | >= 157 | Category 5 Hurricane |
saffirSimpson(35); // { category: 'TD', label: 'Tropical Depression' }
saffirSimpson(74); // { category: 1, label: 'Category 1 Hurricane' }
saffirSimpson(160); // { category: 5, label: 'Category 5 Hurricane' }Throws TypeError for non-finite input and RangeError for negative speeds.
windChill(tempF, windMph) -> number
Wind chill temperature in degrees Fahrenheit using the official 2001 NWS / Environment Canada formula:
WC = 35.74 + 0.6215*T - 35.75*V^0.16 + 0.4275*T*V^0.16with T air temperature in °F and V wind speed in mph (at the standard 10 m
anemometer height).
Validity range. The NWS defines this formula only for air temperature ≤ 50 °F
and wind speed > 3 mph. Outside that domain wind chill is not meaningful, so
this function returns the input air temperature (tempF) unchanged when
tempF > 50 or windMph <= 3. Inside the valid domain it returns the raw
formula value (not rounded); published NWS charts round to the nearest whole
degree, so expect sub-degree differences from a chart cell.
windChill(0, 35); // -27.40... (NWS chart cell: -27)
windChill(40, 5); // 36.47... (NWS chart cell: 36)
windChill(60, 20); // 60 (T > 50 F -> out of range, returns tempF)
windChill(20, 2); // 20 (V <= 3 mph -> out of range, returns tempF)Throws TypeError if either argument is not a finite number, and RangeError
for negative wind speed.
Running the tests
One command, no install step (uses only node:assert):
node test/wind-scale.test.jsThe suite checks round-trip and cross-unit conversions, every Beaufort force boundary (and the value just below it), every Saffir-Simpson category boundary, and ten published NWS wind-chill chart cells.
Status / limitations
- Beaufort m/s thresholds follow the widely published WMO table rounded to one decimal; different sources round the knot-derived cut points slightly differently, so a value sitting exactly on a boundary may differ by one force from another table.
saffirSimpsonexpects 1-minute sustained wind in mph, the U.S. convention. Agencies using 10-minute sustained winds (much of the world) will classify the same storm differently — convert your averaging period first.- Wind chill is only valid for cold, windy conditions (≤ 50 °F, > 3 mph); it is not a general "feels like" index and says nothing about heat or humidity.
License
MIT.
Install
Placeholder name: the
wind-scalebelow is the working slug, not a finalized npm name — see the owner TODO near the top of this README.
npm install wind-scaleconst { convert, beaufort, saffirSimpson, windChill } = require('wind-scale');
convert(10, 'ms', 'kmh'); // 36
beaufort(9.0); // { force: 5, description: 'Fresh breeze', minMs: 8, maxMs: 10.8 }
saffirSimpson(100); // { category: 2, label: 'Category 2 Hurricane' } (sustained mph)
windChill(20, 15); // 6.22 (°F, from tempF=20, windMph=15)