@alanko0511/open-meteo-js
v0.1.3
Published
A Type-safe JavaScript client for the Open-Meteo API
Downloads
298
Maintainers
Readme
@alanko0511/open-meteo-js
A type-safe TypeScript/JavaScript library for the Open-Meteo Weather API. This library uses the JSON API format and transforms the data into an easy-to-use structure (for me at least) with full type safety.
If you need maximum performance, you should check out their official library which uses FlatBuffers. This library is slower because it uses JSON over HTTP with Zod validation, but focuses on developer experience and type safety instead.
Features
- Fully Type-Safe: Response types automatically match your requested variables
- Runtime Validation: Zod schemas validate both inputs and outputs
- Transformed Data: Converts Open-Meteo's parallel arrays into arrays of objects
- Timestamps in Milliseconds: Unix timestamps converted to JavaScript milliseconds (ready for
new Date()) - Type-Safe Units: Units included for all variables with full type safety
Installation
# Using Bun
bun add @alanko0511/open-meteo-js
# Using npm
npm install @alanko0511/open-meteo-js
# Using pnpm
pnpm add @alanko0511/open-meteo-js
# Using Yarn
yarn add @alanko0511/open-meteo-jsUsage
Basic Example
import { forecastAPI } from "@alanko0511/open-meteo-js";
const forecast = await forecastAPI({
latitude: 52.52,
longitude: 13.41,
hourly: ["temperature_2m", "precipitation", "wind_speed_10m"],
daily: ["temperature_2m_max", "temperature_2m_min"],
current: ["temperature_2m", "weather_code"],
});
// TypeScript knows the exact structure
console.log(forecast.hourly[0].temperature_2m); // number
console.log(forecast.hourly[0].precipitation); // number
console.log(forecast.daily[0].temperature_2m_max); // number
console.log(forecast.current.weather_code); // number
// Units are also type-safe
console.log(forecast.hourly_units.temperature_2m); // string (e.g., "°C")
console.log(forecast.daily_units.temperature_2m_max); // string
// These would be TypeScript errors:
// console.log(forecast.hourly[0].cloud_cover); // Error: not requested
// console.log(forecast.hourly_units.cloud_cover); // Error: not requestedData Format
This library transforms the data from parallel arrays to arrays of objects:
Open-Meteo Format (parallel arrays):
{
"hourly": {
"time": [1234567890, 1234571490, ...],
"temperature_2m": [15.2, 15.5, ...],
"precipitation": [0, 0.1, ...]
}
}This Library (array of objects):
{
"hourly": [
{
"time": 1704067200000, // Unix timestamp in milliseconds
"temperature_2m": 15.2,
"precipitation": 0
},
{
"time": 1704070800000, // Unix timestamp in milliseconds
"temperature_2m": 15.5,
"precipitation": 0.1
}
],
"hourly_units": {
"temperature_2m": "°C",
"precipitation": "mm"
}
}Note: Time values are Unix timestamps in milliseconds (JavaScript standard). You can easily convert them to Date objects:
const date = new Date(forecast.hourly[0].time);Advanced Options
const forecast = await forecastAPI({
latitude: 52.52,
longitude: 13.41,
hourly: ["temperature_2m"],
timezone: "Europe/Berlin",
temperature_unit: "fahrenheit",
wind_speed_unit: "mph",
precipitation_unit: "inch",
forecast_days: 7,
past_days: 1,
});Commercial API & Self-Hosted Instances
You can use the commercial Open-Meteo API or self-hosted instances by providing configuration options:
Commercial API with API Key
When you provide an API key, the library automatically uses the commercial API endpoint (https://customer-api.open-meteo.com/v1):
const forecast = await forecastAPI(
{
latitude: 52.52,
longitude: 13.41,
hourly: ["temperature_2m"],
},
{
apiKey: "your-api-key-here",
}
);Self-Hosted Instance
For self-hosted Open-Meteo instances, specify a custom base URL:
const forecast = await forecastAPI(
{
latitude: 52.52,
longitude: 13.41,
hourly: ["temperature_2m"],
},
{
baseUrl: "https://your-domain.com/v1",
}
);Custom Timeout
You can also customize the request timeout (defaults to 30 seconds):
const forecast = await forecastAPI(
{
latitude: 52.52,
longitude: 13.41,
hourly: ["temperature_2m"],
},
{
timeout: 60000, // 60 seconds
}
);Available Variables
Hourly Variables
temperature_2m- Temperature at 2 metersrelative_humidity_2m- Relative humidity at 2 metersdew_point_2m- Dew point at 2 metersapparent_temperature- Apparent temperatureprecipitation_probability- Precipitation probabilityprecipitation- Total precipitation (rain + showers + snow)rain- Rainshowers- Showerssnowfall- Snowfallsnow_depth- Snow depthweather_code- WMO Weather codepressure_msl- Sea level pressuresurface_pressure- Surface pressurecloud_cover- Total cloud covercloud_cover_low- Low cloud covercloud_cover_mid- Mid cloud covercloud_cover_high- High cloud covervisibility- Visibilityevapotranspiration- Evapotranspirationet0_fao_evapotranspiration- Reference evapotranspirationvapour_pressure_deficit- Vapour pressure deficitwind_speed_10m- Wind speed at 10mwind_speed_80m- Wind speed at 80mwind_speed_120m- Wind speed at 120mwind_speed_180m- Wind speed at 180mwind_direction_10m- Wind direction at 10mwind_direction_80m- Wind direction at 80mwind_direction_120m- Wind direction at 120mwind_direction_180m- Wind direction at 180mwind_gusts_10m- Wind gusts at 10mtemperature_80m- Temperature at 80mtemperature_120m- Temperature at 120mtemperature_180m- Temperature at 180msoil_temperature_0cm- Soil temperature at 0cmsoil_temperature_6cm- Soil temperature at 6cmsoil_temperature_18cm- Soil temperature at 18cmsoil_temperature_54cm- Soil temperature at 54cmsoil_moisture_0_1cm- Soil moisture 0-1cmsoil_moisture_1_3cm- Soil moisture 1-3cmsoil_moisture_3_9cm- Soil moisture 3-9cmsoil_moisture_9_27cm- Soil moisture 9-27cmsoil_moisture_27_81cm- Soil moisture 27-81cm
Daily Variables
weather_code- WMO Weather codetemperature_2m_max- Maximum temperaturetemperature_2m_min- Minimum temperatureapparent_temperature_max- Maximum apparent temperatureapparent_temperature_min- Minimum apparent temperaturesunrise- Sunrise timesunset- Sunset timedaylight_duration- Daylight durationsunshine_duration- Sunshine durationuv_index_max- Maximum UV indexuv_index_clear_sky_max- Maximum UV index (clear sky)rain_sum- Rain sumshowers_sum- Showers sumsnowfall_sum- Snowfall sumprecipitation_sum- Precipitation sumprecipitation_hours- Precipitation hoursprecipitation_probability_max- Maximum precipitation probabilitywind_speed_10m_max- Maximum wind speedwind_gusts_10m_max- Maximum wind gustswind_direction_10m_dominant- Dominant wind directionshortwave_radiation_sum- Shortwave radiation sumet0_fao_evapotranspiration- Reference evapotranspiration
Current Variables
temperature_2m- Current temperaturerelative_humidity_2m- Current relative humidityapparent_temperature- Current apparent temperatureis_day- Is it day or nightprecipitation- Current precipitationrain- Current rainshowers- Current showerssnowfall- Current snowfallweather_code- Current weather codecloud_cover- Current cloud coverpressure_msl- Current sea level pressuresurface_pressure- Current surface pressurewind_speed_10m- Current wind speedwind_direction_10m- Current wind directionwind_gusts_10m- Current wind gusts
Type Safety in Action
The response type adapts based on what variables you request:
// Request only temperature
const response1 = await forecastAPI({
latitude: 52.52,
longitude: 13.41,
hourly: ["temperature_2m"],
});
// Works:
// response1.hourly[0].temperature_2m
// response1.hourly_units.temperature_2m
// Type errors:
// response1.hourly[0].precipitation
// response1.hourly_units.precipitation
// Request temperature and precipitation
const response2 = await forecastAPI({
latitude: 52.52,
longitude: 13.41,
hourly: ["temperature_2m", "precipitation"],
});
// Works:
// response2.hourly[0].temperature_2m
// response2.hourly[0].precipitation
// response2.hourly_units.temperature_2m
// response2.hourly_units.precipitation
// Request only daily variables
const response3 = await forecastAPI({
latitude: 52.52,
longitude: 13.41,
daily: ["temperature_2m_max"],
});
// Works:
// response3.daily[0].temperature_2m_max
// Type errors:
// response3.hourly
// response3.currentUnits
Units are automatically included for all requested variables and are also type-safe:
const forecast = await forecastAPI({
latitude: 52.52,
longitude: 13.41,
hourly: ["temperature_2m", "wind_speed_10m"],
temperature_unit: "fahrenheit",
wind_speed_unit: "mph",
});
console.log(forecast.hourly_units.temperature_2m); // "°F"
console.log(forecast.hourly_units.wind_speed_10m); // "mph"
// forecast.hourly_units.precipitation // Type error - not requestedWorking with Timestamps
All time values are returned as Unix timestamps in milliseconds (JavaScript standard):
const forecast = await forecastAPI({
latitude: 52.52,
longitude: 13.41,
hourly: ["temperature_2m"],
});
// Time is a number (milliseconds since Unix epoch)
const timestamp = forecast.hourly[0].time; // e.g., 1704067200000
// Convert to Date when needed
const date = new Date(timestamp);
console.log(date.toISOString()); // "2024-01-01T00:00:00.000Z"
// Or use directly with Date methods
const hours = new Date(forecast.hourly[0].time).getHours();Error Handling
The library validates both input parameters and API responses using Zod:
try {
const forecast = await forecastAPI({
latitude: 52.52,
longitude: 13.41,
hourly: ["temperature_2m"],
});
} catch (error) {
if (error instanceof ZodError) {
// Validation error (invalid params or unexpected API response)
console.error("Validation error:", error.issues);
} else {
// Network or other errors
console.error("Request failed:", error);
}
}