Documentation

Weather Plus

Typed weather data from multiple providers, one API.

Weather Plus unifies NWS, OpenWeather, Tomorrow.io, and Weatherbit into a single contract—reshaping payloads, condition codes, and errors so your application stays consistent even when providers change.

Built by Texture

Install

yarn add weather-plus
# or
npm install weather-plus

First request

Create the SDK, supply the providers you care about, and ask for data at a latitude / longitude. Weather Plus will try providers in order and return as soon as one succeeds.

import WeatherPlus from 'weather-plus';

const client = new WeatherPlus({
  providers: ['weatherbit', 'openweather', 'nws'],
  apiKeys: {
    weatherbit: process.env.WEATHERBIT_API_KEY!,
    openweather: process.env.OPENWEATHER_API_KEY!,
  },
});

const report = await client.getWeather(40.7128, -74.0060);

console.log(report.temperature?.value); // → number in °C
console.log(report.conditions?.value);  // → standardized enum string
console.log(report.provider);            // → 'weatherbit'

Normalized weather schema

All providers are transformed into the same TypeScript contract. The shared schema lives in src/interfaces.ts if you need to dig deeper.

export interface IWeatherData {
  provider: string;
  cached: boolean;
  cachedAt?: string; // ISO-8601 timestamp when served from cache
  temperature?: { value: number; unit: 'C' | 'F' };
  humidity?: { value: number; unit: 'percent' };
  dewPoint?: { value: number; unit: 'C' | 'F' };
  cloudiness?: { value: number; unit: 'percent' };
  conditions?: { value: string; unit: 'string'; original?: string };
}

Provider fallback & timeouts

Provide an ordered list of providers. Optional timeout controls how long each provider is given before the next one is tried.

const client = new WeatherPlus({
  providers: ['openweather', 'tomorrow', 'weatherbit'],
  apiKeys: {
    openweather: process.env.OPENWEATHER_API_KEY!,
    tomorrow: process.env.TOMORROW_API_KEY!,
    weatherbit: process.env.WEATHERBIT_API_KEY!,
  },
  timeout: 4000, // 4s per provider before falling back
});

Caching strategies

In-memory (default)

Every Weather Plus instance ships with an in-memory cache using geohash keys. Nearby lookups map to the same cell, keeping payloads compact while delivering high hit rates for city-centric requests.

Redis

Provide a Redis client to share cache between processes or hosts. Configure TTL and geohash precision to balance freshness and hit rate.

import { createClient } from 'redis';

const redis = createClient({ url: process.env.REDIS_URL });
await redis.connect();

const client = new WeatherPlus({
  providers: ['weatherbit', 'nws'],
  apiKeys: { weatherbit: process.env.WEATHERBIT_API_KEY! },
  redisClient: redis,
  cacheTTL: 900,        // seconds
  geohashPrecision: 6,  // tighter cells for metropolitan areas
});

Runtime options

// Bypass cache for a single call
await client.getWeather(lat, lng, { bypassCache: true });

// Change geohash precision (1–20)
const regionalClient = new WeatherPlus({
  providers: ['openweather'],
  apiKeys: { openweather: process.env.OPENWEATHER_API_KEY! },
  geohashPrecision: 4, // wider cells for national coverage
});

Error taxonomy

Weather Plus wraps provider errors in a shared hierarchy. You can inspect the instance type or code to decide whether to retry, back off, or open a circuit.

import {
  InvalidProviderLocationError,
  WeatherProviderError,
} from 'weather-plus/dist/cjs/errors';

try {
  await client.getWeather(lat, lng);
} catch (error) {
  if (error instanceof InvalidProviderLocationError) {
    // Provider never supports this lat/lng (e.g., NWS outside the US)
  }

  if (error instanceof WeatherProviderError) {
    console.error(error.provider, error.code, error.cause);
    // -> code: 'UpstreamError' | 'UnavailableError' | 'ValidationError' | etc.
  }
}

Outcome reporters

Hook into the provider lifecycle for metrics or logging. Every call emits a success/failure event with latency and error taxonomy.

import {
  ProviderOutcomeReporter,
  setDefaultOutcomeReporter,
} from 'weather-plus/dist/cjs/providers/outcomeReporter';

const reporter: ProviderOutcomeReporter = {
  record(provider, outcome) {
    if (outcome.ok) {
      console.log(`[${provider}] success in ${outcome.latencyMs}ms`);
    } else {
      console.error(
        `[${provider}] failed (${outcome.code}) after ${outcome.latencyMs}ms`,
      );
    }
  },
};

setDefaultOutcomeReporter(reporter);

Provider capabilities

Provider API key Region Notes
National Weather Service (NWS) No United States Free, but limited to US lat/lng and rate-limited by policy.
OpenWeather Yes Global Supports free and paid tiers with robust forecast data.
Tomorrow.io Yes Global Realtime conditions with rich metadata and enterprise plans.
Weatherbit Yes Global Simple paid plans, great for realtime conditions.

Helpful links