Most weather apps are surveillance tools with a weather feature attached. The Weather Channel app has been caught selling precise location data to hedge funds. AccuWeather sent GPS coordinates to third parties even when location sharing was disabled. This guide covers weather apps that respect your privacy — and how to query weather data without any app at all.
The Problem with Popular Weather Apps
Standard weather apps collect:
- Precise GPS coordinates logged with timestamps
- Device identifiers tied to advertising profiles
- Location history sold to data brokers
- Background location access even when the app is closed
Breezy Weather (Android — Open Source)
Fully open-source fork of Geometric Weather with no tracking, available on F-Droid.
- Source: github.com/breezy-weather/breezy-weather
- No account required, no analytics, no ads
- Supports Open-Meteo (no API key, EU-hosted), MET Norway, Pirate Weather
Setup: Install from F-Droid → Settings > Weather Sources → Select Open-Meteo → Set location manually by city name (not GPS).
Organic Maps and Climate Apps
Clima (Android, F-Droid): Uses OpenWeatherMap API. Open-source, no telemetry. Requires a free OpenWeatherMap API key.
Meteo by Alec Saunders (iOS, paid): No tracking, no ads, uses Apple WeatherKit. One-time purchase.
Apple Weather (iOS): Uses WeatherKit. Apple does not share location with advertisers. Better than AccuWeather.
Query Weather Without an App
wttr.in — Terminal
# Current weather for a city
curl wttr.in/London
# Short one-line format
curl "wttr.in/Berlin?format=3"
# Output: Berlin: +12°C
# JSON output
curl "wttr.in/Tokyo?format=j1" | jq '.current_condition[0] | {temp_C, weatherDesc}'
# 3-day forecast
curl "wttr.in/Sydney?format=v2"
wttr.in requires no account or API key. Use a city name rather than your home address.
Open-Meteo API — No Key Required
# Current temperature for Berlin coordinates
curl "https://api.open-meteo.com/v1/forecast?latitude=52.52&longitude=13.41¤t_weather=true" | \
jq '.current_weather | {temperature, windspeed}'
# 7-day forecast
curl "https://api.open-meteo.com/v1/forecast?\
latitude=52.52&longitude=13.41\
&daily=temperature_2m_max,temperature_2m_min,precipitation_sum\
&timezone=Europe/Berlin" | jq '.daily'
Use approximate coordinates (round to 1 decimal place) for better privacy:
lat, lon = 51.5074, -0.1278 # London
lat_approx = round(lat, 1) # 51.5
lon_approx = round(lon, 1) # -0.1
print(f"Use: {lat_approx},{lon_approx}")
MET Norway API
# Free, no account required
curl -H "User-Agent: myapp/1.0 contact@example.com" \
"https://api.met.no/weatherapi/locationforecast/2.0/compact?lat=51.5&lon=-0.1" | \
jq '.properties.timeseries[0].data.instant.details'
Shell Prompt Weather
# Add to ~/.bashrc or ~/.zshrc
echo "London" > ~/.config/weather_city
alias weather='curl -s "wttr.in/$(cat ~/.config/weather_city)?format=3"'
What to Avoid
- The Weather Channel app: Sold location data to IBM and hedge funds
- AccuWeather: Sent GPS to third parties even with sharing disabled
- Weather Underground: Owned by IBM, same data practices as TWC
- Weather apps requiring account creation: Ties location to an identity
Building Your Own Weather CLI Tool
For the ultimate privacy, host your own weather tool that queries public APIs and caches results locally:
#!/usr/bin/env python3
# weather.py — local weather tool using Open-Meteo
import requests
import json
from datetime import datetime
from pathlib import Path
def get_weather(lat, lon):
"""Fetch weather without storing or tracking location."""
url = "https://api.open-meteo.com/v1/forecast"
params = {
"latitude": lat,
"longitude": lon,
"current_weather": True,
"hourly": "temperature_2m,precipitation,windspeed_10m",
"daily": "temperature_2m_max,temperature_2m_min,precipitation_sum,windgusts_10m",
"temperature_unit": "celsius",
"timezone": "auto"
}
response = requests.get(url, params=params)
response.raise_for_status()
return response.json()
def format_weather(data):
"""Pretty print weather data."""
current = data["current_weather"]
daily = data["daily"]
print(f"Temperature: {current['temperature']}°C")
print(f"Wind: {current['windspeed']} km/h")
print(f"Weather code: {current['weathercode']}")
print("\n7-day forecast:")
for i in range(7):
high = daily["temperature_2m_max"][i]
low = daily["temperature_2m_min"][i]
rain = daily["precipitation_sum"][i]
print(f" Day {i+1}: {high}°/{low}°C, {rain}mm rain")
if __name__ == "__main__":
# Use approximate coordinates (rounding protects location privacy)
lat, lon = 51.5, -0.1 # London approximation
data = get_weather(lat, lon)
format_weather(data)
Run locally:
chmod +x weather.py
./weather.py
No account, no tracking, no ads, no data storage.
Weather Data Providers Comparison
| Provider | Free | No API Key | Privacy Policy | Data Retention |
|---|---|---|---|---|
| Open-Meteo | Yes | Yes | Minimal | No personal data |
| MET Norway | Yes | Yes | EU/GDPR | Logs aggregated only |
| wttr.in | Yes | Yes | See rainbo.ws | No personal data |
| Pirate Weather | Yes | No | Ad-free, privacy-focused | Limited logs |
| OpenWeatherMap | Free tier | Registration | Limited free tier | Log location for paid users |
| NOAA (US) | Yes | Yes | US government | Public data only |
For maximum privacy, stack rank providers:
- Open-Meteo (best for EU/global)
- MET Norway (best for Northern Europe)
- wttr.in (best for simplicity)
- Pirate Weather (best for US)
Avoid commercial weather APIs that require registration — they track your lookups.
Privacy-Respecting Configuration
On Android with Breezy Weather, disable location permissions entirely:
- Do NOT grant GPS permission
- Search location by city name only
- Disable location services in system settings when not actively using weather
- Use a rounded approximation of your city (e.g., “London” not “51.5074, -0.1278”)
On iOS with Meteo:
- Settings > Meteo > Location → “Never”
- Manually enter city name at startup
This prevents the app from:
- Recording your GPS coordinates
- Tracking movements between locations
- Building location history
Checking What Your Current App Sends
If you suspect your weather app is leaking data:
# On a rooted Android device or via mitmproxy:
mitmproxy --mode reverse --listen-port 8080
# Configure device to use mitmproxy as HTTP proxy
# Then use your weather app and observe HTTP requests
# Look for:
# - Location data in URL parameters
# - Unique device identifiers
# - Analytics domain calls
# - Unencrypted HTTP (not HTTPS)
Most weather apps claim location isn’t tracked but still send it to analytics backends. DNS-level blocking helps:
# On a network with Pi-hole installed:
# Block domains: analytics.*, ads.*, track.*
# This prevents app-level tracking even if the app tries to send data
Weather API Rate Limits and Caching
If building your own tool, cache results locally to reduce API calls:
#!/bin/bash
# weather.sh with local caching
CACHE_DIR="$HOME/.cache/weather"
CACHE_FILE="$CACHE_DIR/forecast.json"
CACHE_AGE_HOURS=3
mkdir -p "$CACHE_DIR"
if [ -f "$CACHE_FILE" ]; then
AGE=$(($(date +%s) - $(stat -f%m "$CACHE_FILE" 2>/dev/null || stat -c%Y "$CACHE_FILE")))
AGE_HOURS=$((AGE / 3600))
if [ $AGE_HOURS -lt $CACHE_AGE_HOURS ]; then
cat "$CACHE_FILE" && exit 0
fi
fi
# Fetch fresh data
curl -s "https://api.open-meteo.com/v1/forecast?latitude=51.5&longitude=-0.1¤t_weather=true" | tee "$CACHE_FILE"
This reduces API calls to once per 3 hours, protecting your privacy further.
Related Reading
- Privacy-Focused Maps and Navigation Apps
- Privacy Risks of Smart Speakers Explained
- How to Remove Metadata from PDF Files
- Best Accessible Privacy-Focused Keyboard App for Users with
- AI Coding Assistant Session Data Lifecycle
- AI Tools for Generating Mobile App Deep Linking
Built by theluckystrike — More at zovo.one