A beautiful, feature-rich weather CLI for your terminal.
Sparklines, route planning, live dashboards, marine forecasts, measured stations, and more — core forecasts need no API key.
Most weather CLIs give you temperature and a condition. Raindrop gives you everything:
- Sparkline graphs —
▁▂▃▅▇█▅▃temperature and precipitation trends at a glance - Technical analysis — EMA crossovers, rate-of-change, and volatility on forecasts
- Ensemble lab — inspect every model member, uncertainty bands, outliers, thresholds, and consensus departure
- Real driving routes — weather checkpoints along actual roads via OpenStreetMap
- Full-screen dashboard — live TUI with auto-refresh
- Astronomical data — moon phases, golden hour, blue hour, daylight tracking
- Marine forecasts — wave height, swell, water temp for coastal trips
- Zero-key core weather — forecasts, dashboards, routes, air quality, alerts, and astronomy use free/open APIs
- Optional measured stations — nearby personal/official observations via Xweather when you configure a key
Requirements: Python 3.12+
# pip
pip install rdrop
# From source
git clone https://github.com/binarydoubling/raindrop.git
cd raindrop
pip install -e .raindrop current Seattle # current conditions
raindrop window Seattle # sensory weather scene
raindrop ensemble forecast Seattle -n 48 # member spread and percentiles
raindrop stations nearby Fairbanks # nearby PWS observations (optional Xweather key)
raindrop hourly "New York" --spark --hours 12 # sparkline forecast
raindrop daily Portland # 10-day with trend analysis
raindrop dashboard Seattle --refresh 300 # live full-screen TUI
raindrop route "Seattle" "San Francisco" -i 100 # road trip weather
raindrop aqi Beijing # air quality index
raindrop favorites add home "Seattle, WA" # save a location
raindrop current home # use it anywhereTranslate weather variables into the feel of standing outside: air texture, sky, light, motion, surfaces, and distance.
raindrop window Seattle
raindrop outside Tokyo --compactEnsembles run the same forecast model with multiple plausible initial conditions. Agreement among members suggests greater confidence; disagreement exposes uncertainty that a single deterministic forecast hides. Raindrop analyzes the Open-Meteo Ensemble API directly and requires no API key.
Important
Ensemble consensus is not historical forecast skill. member and rank compare members with the same run's consensus, not with later observations, so the closest member is not necessarily the most accurate one.
# Default: NOAA GEFS, hourly temperature, next 24 hours
raindrop ensemble forecast Fairbanks
# Temperature uncertainty over the next 72 hours
raindrop ensemble forecast Fairbanks -v temperature_2m -n 72
# Inspect one perturbed member against the ensemble consensus
raindrop ensemble member Fairbanks --member 12 -v temperature_2m -n 72
# Find the 10 members closest to consensus over the requested horizon
raindrop ensemble rank Fairbanks -v temperature_2m -n 72 --top 10
# Discover model identifiers
raindrop ensemble modelsThe default model is ncep_gefs_seamless. Every invocation analyzes exactly one model so member identities and consensus statistics remain unambiguous.
ensemble forecast summarizes all available members at each forecast step. Human output shows the control value, distribution center, uncertainty interval, and number of members returned:
raindrop ensemble forecast Fairbanks -n 48Request several variables by repeating -v/--variable:
raindrop ensemble forecast Fairbanks \
-v temperature_2m \
-v precipitation \
-v wind_speed_10m \
-n 24Variable names are passed directly to Open-Meteo rather than restricted by a Raindrop allow-list. Common hourly variables include:
temperature_2m
relative_humidity_2m
precipitation
weather_code
wind_speed_10m
wind_gusts_10m
wind_direction_10m
Model and regional availability varies. If Open-Meteo does not provide a requested variable for the selected model, Raindrop reports the missing ensemble data.
Continuous variables include mean, median, population standard deviation, minimum, maximum, full spread, requested percentiles, members outside the 1.5-IQR bounds, and the fraction within one standard deviation. Raindrop avoids misleading linear statistics for special variable types:
weather_codeandis_dayuse categorical mode, frequency, and agreement.wind_direction_*uses a circular mean and directional concentration, so 359° and 1° average near north rather than south.
The default percentile set is 10,25,50,75,90. Supply any finite percentiles from 0 through 100:
raindrop ensemble forecast Fairbanks \
-v temperature_2m \
--percentiles 5,25,50,75,95 \
-n 48The terminal uncertainty column spans the lowest through highest requested percentile. JSON contains every requested percentile and the complete member values.
For one variable, calculate the fraction of available members above or below a threshold:
# Probability that temperature falls below 32°F with imperial settings
raindrop ensemble forecast Fairbanks \
-v temperature_2m \
--threshold 32 \
--operator below \
-n 48
# Probability that hourly precipitation exceeds 0.1 inches
raindrop ensemble forecast Fairbanks \
-v precipitation \
--threshold 0.1 \
--operator above \
-n 24Thresholds use the units in raindrop config show; they are not automatically interpreted as Celsius, Fahrenheit, millimeters, or inches independently of that configuration. Threshold analysis accepts exactly one --variable so the probability has one clear meaning. Comparisons are strict (> or <), not inclusive.
Add --daily to request daily rather than hourly variables:
raindrop ensemble forecast Fairbanks \
--daily \
-v temperature_2m_max \
-v temperature_2m_min \
-v precipitation_sum \
-n 14Without -v, daily mode defaults to temperature_2m_mean. Daily requests support up to 36 periods:
raindrop ensemble forecast Fairbanks --daily -n 36Hourly requests default to 24 periods and support up to 864. The selected model may have a shorter forecast horizon than the command-level limit.
ensemble member compares one member with the same-step ensemble consensus throughout the requested horizon:
# Member 0 is the unsuffixed control forecast when the model returns one
raindrop ensemble member Fairbanks \
--member 0 \
-v temperature_2m \
-n 48
# Evaluate the same perturbed member for two variables
raindrop ensemble member Fairbanks \
--member 12 \
-v temperature_2m \
-v precipitation \
-n 72For continuous variables, the evaluation includes the member value, median consensus, signed departure, percentile position, z-score, and outlier status; human tables show the compact value, consensus, departure, and position fields. Categorical variables report whether the member matches the mode; wind direction reports angular departure and directional agreement. Horizon summaries include bias, mean absolute departure, RMSE from consensus, and outlier rate.
Member IDs are discovered from the returned columns rather than assumed from a fixed local list. Raindrop reports an error if the requested member is unavailable for any selected variable.
ensemble rank accepts one variable and ranks members by RMSE from the same-run consensus across the requested horizon:
raindrop ensemble rank Fairbanks \
-v temperature_2m \
-n 72 \
--top 10
raindrop ensemble rank Fairbanks \
-v precipitation \
-n 48 \
--top 15The ranking includes sample count, signed bias, mean absolute departure, RMSE, and outlier rate. For categorical variables, departure means disagreement with the mode; for wind direction, it is angular departure. This ranks conformity, not real-world accuracy.
List the known model identifiers and their advertised regions, member counts, and horizons:
raindrop ensemble models
raindrop ensemble models --jsonExamples using a non-default model:
# ECMWF's 51-member global IFS ensemble
raindrop ensemble forecast Fairbanks \
-m ecmwf_ifs025_ensemble \
-v temperature_2m \
-n 72
# Google's 64-member WeatherNext 2 ensemble
raindrop ensemble forecast Fairbanks \
-m google_weathernext2_ensemble \
-v temperature_2m \
-n 72Known identifiers are:
| Identifier | Model | Region | Members | Horizon |
|---|---|---|---|---|
icon_seamless_eps |
DWD ICON EPS Seamless | Best available ICON domain | 40 | 7.5d |
icon_global_eps |
DWD ICON Global EPS | Global | 40 | 7.5d |
icon_eu_eps |
DWD ICON EU EPS | Europe | 40 | 5d |
icon_d2_eps |
DWD ICON D2 EPS | Central Europe | 20 | 2d |
ncep_gefs_seamless |
NOAA GFS Ensemble Seamless | Global | 31 | 35d |
ncep_gefs025 |
NOAA GFS Ensemble 0.25° | Global | 31 | 10d |
ncep_gefs05 |
NOAA GFS Ensemble 0.5° | Global | 31 | 35d |
ncep_aigefs025 |
NOAA AI GEFS 0.25° | Global | 31 | 16d |
ecmwf_ifs025_ensemble |
ECMWF IFS 0.25° Ensemble | Global | 51 | 15d |
ecmwf_ifs_europe_ensemble |
ECMWF IFS 9 km Ensemble | Europe | 51 | 15d |
ecmwf_aifs025_ensemble |
ECMWF AIFS 0.25° Ensemble | Global | 51 | 15d |
ecmwf_aifs_europe_ensemble |
ECMWF AIFS 31 km Ensemble | Europe | 51 | 15d |
gem_global_ensemble |
Canadian GEM Global Ensemble | Global | 21 | 16d |
bom_access_global_ensemble |
BOM ACCESS Global Ensemble | Global | 18 | 10d |
ukmo_global_ensemble_20km |
UKMO Global Ensemble | Global | 18 | 8d |
ukmo_uk_ensemble_2km |
UKMO UK Ensemble | United Kingdom | 3 | 5d |
meteoswiss_icon_ch1_ensemble |
MeteoSwiss ICON CH1 | Central Europe | 11 | 33h |
meteoswiss_icon_ch2_ensemble |
MeteoSwiss ICON CH2 | Central Europe | 21 | 12h |
google_weathernext2_ensemble |
Google WeatherNext 2 | Global | 64 | 15d |
These are convenient known identifiers, not a guarantee of current Open-Meteo availability. Supported variables, actual member count, update timing, region, and usable horizon remain provider-controlled.
Hourly commands default to an hourly time grid. Select another Open-Meteo ensemble resolution when the model and variable support it:
raindrop ensemble forecast Fairbanks \
-v temperature_2m \
--temporal-resolution hourly_6 \
-n 40Choices are native, hourly, hourly_3, and hourly_6. -n/--periods counts returned time steps: with hourly_6, for example, 40 periods represent 240 hours.
Every ensemble subcommand supports JSON output:
raindrop ensemble forecast Fairbanks \
-v temperature_2m \
-n 24 \
--json
raindrop ensemble member Fairbanks \
--member 12 \
-v wind_speed_10m \
-n 48 \
--json
raindrop ensemble rank Fairbanks \
-v temperature_2m \
-n 72 \
--jsonWith jq, extract the five members closest to consensus:
raindrop ensemble rank Fairbanks \
-v temperature_2m \
-n 72 \
--json | jq '.ranking[:5]'Forecast JSON includes location and source metadata, interval, units, every member value, and the complete per-step analysis. Member JSON includes per-step evaluations and horizon summaries. Rank JSON labels its metric explicitly as departure from ensemble consensus rather than forecast skill.
All commands accept -c/--country to disambiguate geocoding. If a default location is configured, omit the location argument:
raindrop config set location Fairbanks
raindrop ensemble forecast -n 48Use raindrop --no-cache ensemble ... to bypass cached API responses, and append --help to any level for the authoritative option list:
raindrop ensemble --help
raindrop ensemble forecast --help
raindrop ensemble member --help
raindrop ensemble rank --helpNearby personal weather station and official station observations through Xweather. These are measured station readings with station IDs, source classification, timestamps, QC/trust status, and freshness — separate from model/gridded conditions returned by raindrop current.
raindrop stations nearby Fairbanks
raindrop stations nearby Fairbanks --kind pws
raindrop stations current PWS_SM9110Xweather is optional and requires credentials. Human output includes the required attribution: Powered by Vaisala Xweather.
EMA crossovers, rate-of-change indicators, and trend detection applied to weather data.
Plan road trips with weather at every checkpoint along the actual driving route.
Moon phases, golden hour, blue hour, and weekly daylight tracking.
Full-screen TUI powered by Rich with automatic refresh.
raindrop dashboard Seattle --refresh 300| Command | Description | Example |
|---|---|---|
window / outside |
First-person weather scene | raindrop window Seattle |
current |
Current conditions | raindrop current Seattle |
ensemble |
Ensemble members and uncertainty | raindrop ensemble forecast Seattle |
stations |
Measured station observations | raindrop stations nearby Fairbanks |
hourly |
Hourly forecast (48h) | raindrop hourly Seattle --spark |
daily |
10-day forecast with trends | raindrop daily Seattle |
dashboard |
Full-screen live TUI | raindrop dashboard Seattle |
route |
Weather along a driving route | raindrop route "A" "B" -i 50 |
compare |
Compare multiple locations | raindrop compare NYC LA Chicago |
alerts |
NWS weather alerts (US) | raindrop alerts Seattle |
aqi |
Air quality index | raindrop aqi Seattle |
astro |
Moon phase, golden hour | raindrop astro Seattle |
marine |
Ocean/wave forecasts | raindrop marine "San Diego" |
clothing |
What to wear | raindrop clothing Seattle |
history |
Compare with past years | raindrop history Seattle |
discussion |
NWS forecast discussion | raindrop discussion Seattle |
precip |
Precipitation totals | raindrop precip Seattle --days 7 |
fav / favorites |
Manage saved locations | raindrop favorites list |
config |
View/edit settings | raindrop config show |
--no-cache Bypass the API response cache for fresh data
--version Show the installed version
--help Show help for any command
Most data commands also support --json for scripting and -c/--country for ISO country filtering.
Use raindrop config set units metric|imperial to switch unit presets.
Settings live at $RAINDROP_CONFIG_DIR/config.json, $XDG_CONFIG_HOME/raindrop/config.json, or ~/.config/raindrop/config.json.
API responses are cached under $RAINDROP_CACHE_DIR, $XDG_CACHE_HOME/raindrop, or ~/.cache/raindrop.
Optional Xweather credentials for Xweather-backed forecasts and raindrop stations can be supplied with XWEATHER_API_KEY or a mode-0600 JSON file at the same config directory, e.g. ~/.config/raindrop/xweather.json:
{"api_key":"<your combined Xweather API key>"}Existing forecast/current commands remain keyless through Open-Meteo fallback. With weather_provider=auto, Raindrop uses Xweather when credentials are configured unless an Open-Meteo model is selected. raindrop config show only reports Xweather as configured/not configured and never prints the key.
raindrop config show # view current settings
raindrop config set units metric # switch to metric
raindrop config set weather_provider xweather # prefer Xweather explicitly
raindrop config set location "NYC" # set default location
raindrop config cache # view cache stats
raindrop config cache --clear # clear cache| Setting | Values | Default | Description |
|---|---|---|---|
units |
imperial, metric |
imperial |
Shortcut that updates the unit fields below |
temperature_unit |
fahrenheit, celsius |
fahrenheit |
Temperature display unit |
wind_speed_unit |
mph, kmh, ms, kn |
mph |
Wind speed display unit |
precipitation_unit |
mm, inch |
mm |
Precipitation display unit |
location |
any string | none | Default location |
country_code |
ISO 3166-1 alpha-2 | none | Default country filter |
weather_provider |
auto, open-meteo, xweather |
auto |
Forecast provider; auto prefers configured Xweather, otherwise Open-Meteo |
model |
auto or raindrop config models value |
auto |
Open-Meteo forecast model |
Click provides completions directly from the installed command:
# Bash: add to ~/.bashrc
eval "$(_RAINDROP_COMPLETE=bash_source raindrop)"
# Zsh: add to ~/.zshrc
eval "$(_RAINDROP_COMPLETE=zsh_source raindrop)"
# Fish: add to ~/.config/fish/config.fish
_RAINDROP_COMPLETE=fish_source raindrop | sourceRaindrop combines free/open APIs with optional credentialed Xweather integration:
| API | Purpose |
|---|---|
| Open-Meteo | Forecasts, ensemble members, historical data, air quality, geocoding |
| OSRM | Real driving routes via OpenStreetMap |
| NWS | Weather alerts and forecast discussions (US) |
| Xweather | Optional forecasts/current conditions and measured personal/official station observations |
The entire project has only 2 runtime dependencies (Click and Rich). HTTP, caching, geocoding, credentials, and astronomical calculations are all handled with Python's standard library.
- Weather window scene engine that infers air texture, sky, light, motion, surface, and horizon from combined variables
- Provider-neutral weather commands normalized across Open-Meteo and Xweather
- Ensemble-member analysis with continuous, categorical, and circular statistics
- Measured station observations with provider/source identity, timestamps, QC/trust labels, freshness filtering, and safe credential-free cache keys
- Sparklines via Unicode block characters (
▁▂▃▄▅▆▇█) - EMA crossovers and rate-of-change analysis on temperature data
- Pure-Python astronomy — moon phases and daylight calculations with no external libs
- Distance sampling along OSRM routes for weather checkpoints
- File-based cache with SHA256 keys and endpoint-specific TTLs
- 14 weather models selectable: ECMWF, GFS, HRRR, ICON, ARPEGE, AROME, UKMO, GEM, JMA, MetNo, and more
The feature screenshots in this README are real CLI output captured as SVGs:
python scripts/capture.py # capture all commands
python scripts/capture.py current # capture a specific commandgit clone https://github.com/binarydoubling/raindrop.git
cd raindrop
uv sync
uv run pytest
uv run ruff check
uv run pyrightBuilt with coffee and curiosity in the Pacific Northwest — where checking the weather is a lifestyle.