The best free OpenWeatherMap alternative for most developers is Open-Meteo. It needs no API key and no credit card, and it returns similar current, hourly and daily data in a single request. If you need a commercial free tier, WeatherAPI.com gives you 100,000 calls a month. For old Dark Sky-style code, Pirate Weather is the closest match.
Developers usually start looking for an alternative for one of three reasons. One Call API 3.0 asks for a payment card even on the free allowance. The free allowance of 1,000 calls a day runs out on a busy app. Or the legacy 2.5 One Call endpoint they relied on was retired. This guide compares the alternatives on the things that matter when you migrate, and shows how to map OpenWeatherMap's fields onto each one.
OpenWeatherMap vs the alternatives at a glance
| API | Key | Card needed | Free allowance | Forecast range (free) | Commercial use free |
|---|---|---|---|---|---|
| OpenWeatherMap One Call 3.0 | Yes | Reported for 3.0 | 1,000 calls/day | 8 days daily | Yes (billed above free calls) |
| Open-Meteo | No | No | 10,000 calls/day | Up to 16 days | No (non-commercial) |
| WeatherAPI.com | Yes | No | 100,000 calls/month | 3 days | Yes |
| Pirate Weather | Yes (free) | No | Free tier | 7+ days | Check terms |
| Tomorrow.io | Yes | No | 500 calls/day | Several days | Check terms |
| Visual Crossing | Yes | No | Daily record limit | 15 days | Yes |
| Weatherstack | Yes | No | 100 calls/month | Paid plans only | Yes |
| US Weather (NWS) | No | No | Fair use | 7 days | Yes (US only) |
Limits are from each provider's pricing page in October 2026. In our daily health check, all eight were online on October 24, 2026.
How OpenWeatherMap fields map to the alternatives
The trickiest part of migrating is the data shape. Here's how the common One Call fields translate:
| OpenWeatherMap One Call | Open-Meteo | WeatherAPI.com |
|---|---|---|
current.temp |
current.temperature_2m |
current.temp_c |
current.feels_like |
current.apparent_temperature |
current.feelslike_c |
current.humidity |
current.relative_humidity_2m |
current.humidity |
current.wind_speed (m/s) |
current.wind_speed_10m (km/h by default) |
current.wind_kph |
current.weather[0].id |
current.weather_code (WMO code) |
current.condition.code |
daily[i].temp.max |
daily.temperature_2m_max[i] |
forecast.forecastday[i].day.maxtemp_c |
daily[i].pop |
daily.precipitation_probability_max[i] (%) |
forecast.forecastday[i].day.daily_chance_of_rain |
Two gotchas: Open-Meteo returns arrays per variable (daily.temperature_2m_max[0]), not an array of objects. And its wind speed defaults to km/h; add wind_speed_unit=ms to match OpenWeatherMap.
Option 1: Open-Meteo (no key, best overall)
async function getWeather(lat, lon) {
const params = new URLSearchParams({
latitude: lat,
longitude: lon,
current: "temperature_2m,apparent_temperature,relative_humidity_2m,wind_speed_10m,weather_code",
daily: "temperature_2m_max,temperature_2m_min,precipitation_probability_max",
wind_speed_unit: "ms",
timezone: "auto",
});
const res = await fetch(`https://api.open-meteo.com/v1/forecast?${params}`);
if (!res.ok) throw new Error(`Open-Meteo ${res.status}`);
const d = await res.json();
// Reshape into OpenWeatherMap-like objects so the rest of your app doesn't change
return {
current: {
temp: d.current.temperature_2m,
feels_like: d.current.apparent_temperature,
humidity: d.current.relative_humidity_2m,
wind_speed: d.current.wind_speed_10m,
weather_code: d.current.weather_code,
},
daily: d.daily.time.map((date, i) => ({
date,
temp: { max: d.daily.temperature_2m_max[i], min: d.daily.temperature_2m_min[i] },
pop: d.daily.precipitation_probability_max[i] / 100,
})),
};
}
The adapter keeps your UI code untouched. Only the fetch layer changes.
Weather icons: Open-Meteo returns WMO weather codes (0 = clear, 61 = rain, 95 = thunderstorm) instead of OpenWeatherMap's condition IDs and icons. Map the codes to your own icon set; there are about 28 to cover.
When not to use it: for commercial products on the free endpoint. Open-Meteo's free API is for non-commercial use, and paid plans start at 1 million calls a month.
Option 2: WeatherAPI.com (commercial-friendly free tier)
WeatherAPI.com is the most direct swap for a commercial app: you need a free key but no card, and you get 100,000 calls a month. It accepts a city name, postcode, IP address or lat,lon in a single q parameter.
import os
import requests
def get_weather(lat: float, lon: float):
res = requests.get(
"https://api.weatherapi.com/v1/forecast.json",
params={"key": os.environ["WEATHERAPI_KEY"], "q": f"{lat},{lon}", "days": 3},
timeout=10,
)
res.raise_for_status()
d = res.json()
return {
"temp": d["current"]["temp_c"],
"feels_like": d["current"]["feelslike_c"],
"daily": [
{"date": f["date"], "max": f["day"]["maxtemp_c"], "min": f["day"]["mintemp_c"]}
for f in d["forecast"]["forecastday"]
],
}
The free plan's limits are a 3-day forecast and one day of history. Paid plans start at $7 a month for 3 million calls.
Option 3: Pirate Weather (for Dark Sky-style code)
If your code was written for Dark Sky, which many OpenWeatherMap migrations started from, Pirate Weather keeps the same currently / hourly / daily response shape. You need a free API key. Note that the public-apis list marks it as keyless, but unauthenticated requests now get a 401.
curl "https://api.pirateweather.net/forecast/$PIRATE_WEATHER_KEY/51.51,-0.13?units=si"
Option 4: Tomorrow.io (hyperlocal, low volume)
Tomorrow.io has excellent minute-level precipitation data, but its free plan allows only 500 requests a day and 25 an hour. It fits a single-location dashboard, not a multi-user app.
Option 5: Visual Crossing (history and analytics)
If you used OpenWeatherMap's historical or statistics APIs, Visual Crossing is the better fit: one request returns a date range of history plus forecast, and the free plan allows commercial use within its daily record limit.
Option 6: Weatherstack (simple current weather)
Weatherstack is easy to use, but its free plan includes only 100 calls a month, and forecasts need a paid plan (from $9.99/month for 50,000 calls).
Option 7: National Weather Service (US only, official)
For US-only apps, the National Weather Service API is free and official, with no key. Send a User-Agent header with contact details, and resolve coordinates to a forecast grid first via /points/{lat},{lon}.
Migration checklist
-
Put an adapter in front of the provider (like the
getWeatherexample above) so the provider is swappable. -
Convert units explicitly. OpenWeatherMap's
units=metricgives m/s wind; the alternatives default differently. - Rebuild your icon mapping from the new provider's condition codes.
- Re-check your cache TTL. Forecast models update every 1–6 hours, so a 10–30 minute cache is plenty.
- Keep a fallback. Our OpenWeatherMap alternatives page ranks every comparable API by uptime and access, updated daily.
Should you leave OpenWeatherMap at all?
Not necessarily. 1,000 free calls a day with a daily spending cap is enough for many small apps, and OpenWeatherMap's ecosystem of tutorials and libraries is unmatched. Switch if you can't or won't add a card, need more than about 30,000 calls a month on a free tier, or just want a keyless API for a prototype.
FAQ
What is the best free alternative to OpenWeatherMap?
Open-Meteo for non-commercial projects (no key, 10,000 calls a day) and WeatherAPI.com for commercial ones (100,000 free calls a month with a key).
Is there an OpenWeatherMap alternative without a credit card?
Yes. Open-Meteo needs no account at all, and WeatherAPI.com, Pirate Weather and Visual Crossing only need a free sign-up with no card.
Is Open-Meteo as accurate as OpenWeatherMap?
Open-Meteo combines forecasts from national weather services (such as DWD, NOAA and Météo-France) and picks the best model for each location. For most apps, accuracy is comparable; test both against your own locations.
How long does it take to migrate from OpenWeatherMap?
With an adapter layer like the one above, a typical app switches in under an hour. Most of the time goes on mapping icons and units.

Top comments (0)