SkyCast — Advanced Weather Intelligence
A full-featured, real-time weather progressive web application built with vanilla HTML, CSS, and JavaScript. No frameworks. No build tools. Just clean, well-structured code.
Developer
Features
GPS Location
Automatically detects the user's precise location using the browser Geolocation API, with graceful fallback to city search.
Live Weather
Fetches real-time temperature, feels-like, humidity, wind, pressure, UV index, and visibility from Open-Meteo.
24-Hour Forecast
Hourly breakdown for the next 24 hours including rain probability and weather icon per hour.
14-Day Forecast
Extended 14-day daily forecast with high/low temperatures, rain probability, and average humidity.
Air Quality Index
US AQI with animated ring gauge, PM2.5, PM10, NO₂ and O₃ pollutant bars, and health advice text.
City Compare
Side-by-side weather comparison of any two cities worldwide with instant API look-up.
Saved Favorites
Up to 12 locations saved with exact coordinates in localStorage — favorites reload instantly and can never fail to geocode.
Sun Progress Bar
Animated sunrise-to-sunset arc showing real-time sun position based on local timezone data.
Live Search Suggestions
Type-ahead autocomplete for any place worldwide — country flags, region subtitles, full keyboard navigation and recent-search history.
24-Hour Trend Chart
Chart.js line chart of the next 24 hours: temperature curve with gradient fill plus rain-probability bars on a second axis.
Live Rain Radar
Animated precipitation radar centered on the current location, powered by RainViewer and Leaflet with play/pause/step controls.
Weather Alerts
Auto-derived advisory banners for extreme heat, very-high UV, strong winds, thunderstorms, heavy rain, unhealthy air and low visibility.
Installable PWA
Web app manifest + service worker: installs to home screen or desktop and keeps the shell cached for offline use.
Moon Phase & Theming
Locally-computed moon phase chip, plus ambient background orbs that retint to match live conditions (clear, rain, storm, snow, fog, night).
File Structure
The project is organised into modular folders — split by responsibility, easy to maintain and extend.
├── index.html ← full HTML structure
├── documentation.html ← this file
├── manifest.json ← PWA manifest
├── sw.js ← service worker (offline)
├── LICENSE ← MIT license
├── README.md ← complete user guide
├── assets/ ← favicon, PWA icons, demo data
├── css/ ← base · layout · components · responsive
└── js/ ← config · utils · api · search · charts · map · render · app
Data Flow
SkyCast follows a simple, linear data pipeline from user action to rendered UI.
User Action
User opens the app — the last viewed location restores instantly from localStorage. Otherwise: search a suggestion, click a city chip, or press the GPS button.
Geocoding
Open-Meteo Geocoding API converts a city name to latitude/longitude coordinates. For GPS, Nominatim (OSM) does the reverse — coords → human-readable location name.
Parallel API Fetch
Two API calls fire simultaneously via Promise.allSettled(): the Open-Meteo weather API (current + hourly + daily) and the Open-Meteo Air Quality API (AQI + pollutants). An AQI failure never blocks the weather render.
Data Normalisation
Raw API responses are transformed into a single currentWeatherData object. Hourly data is sliced from the location's timezone-accurate current hour; daily data is iterated into 14 day objects with computed average humidity.
Render
renderDashboard() calls each sub-renderer in order: hero → metrics → AQI → hourly → 14-day forecast → alerts → chart → radar. The location is then persisted for the next visit.
APIs Used
Open-Meteo Weather API Free · No Key
Provides current conditions (temperature, humidity, wind, pressure, UV, cloud cover, visibility, precipitation), plus hourly and 14-day daily forecasts. open-meteo.com
Open-Meteo Air Quality API Free · No Key
Returns US AQI, PM2.5, PM10, nitrogen dioxide (NO₂) and ozone (O₃) for any coordinates. air-quality-api.open-meteo.com
Open-Meteo Geocoding API Free · No Key
Converts city names to latitude/longitude. Used for city search and the global capitals dropdown. geocoding-api.open-meteo.com
Nominatim / OpenStreetMap Free · No Key
Reverse geocoding — converts GPS coordinates to a human-readable location name (village, district, state, country). nominatim.openstreetmap.org
RainViewer Free · No Key
Animated precipitation radar frames for the Live Rain Radar map. rainviewer.com
Esri Dark Gray Canvas Free
Key-less dark base map tiles rendered underneath the radar overlay. arcgisonline.com
Zero API keys required. SkyCast intentionally uses only free, open APIs with no authentication requirement. This means it can be deployed and run by anyone without signing up for any service.
Local Setup
SkyCast requires no build tools, no npm, no Node.js. All you need is a browser and a local static file server (to satisfy browser CORS restrictions on the Geolocation API).
Option A — VS Code Live Server (Recommended)
Install the Live Server extension in VS Code, right-click index.html and choose Open with Live Server.
Option B — Python HTTP Server
# Navigate to the project folder cd skycast/ # Python 3 python -m http.server 8080 # Then open http://localhost:8080 in your browser
Option C — Node.js serve
npx serve .
# Then open the URL shown in terminal
Note: GPS will not work if you open index.html directly as a file:// URL. A local server is required for the Geolocation API to function correctly.
Deployment
SkyCast is a fully static application — deploy it anywhere that serves static files. The live version runs on Cloudflare Pages at sky-cast.pages.dev.
Git Workflow
# First-time setup git init git remote add origin https://github.com/username/WeatherApp.git git add . git commit -m "First commit" git branch -M main git push -u origin main # Subsequent pushes git add . git commit -m "update" git push
Cloudflare Pages
Connect your GitHub repo to Cloudflare Pages. Set build command to none and output directory to /. Every push auto-deploys.
GitHub Pages
Enable GitHub Pages on the main branch in repository settings. The site will be live at username.github.io/WeatherApp.
JS Module Reference
| Module / Function | File | Description |
|---|---|---|
| CONFIG / APP_INFO / API | js/config.js | App metadata, API endpoints, persisted state, weather-code & level tables |
| makeLocationObj() | js/utils.js | Canonical saved-location shape: { id, name, label, lat, lon } |
| addFavorite() / removeFavorite() | js/utils.js | Coordinate-accurate favorites store (localStorage) |
| getMoonPhase() | js/utils.js | Locally-computed moon phase with illumination percentage |
| searchGeocode() | js/api.js | Multi-result geocoding powering live suggestions |
| loadLocation() | js/api.js | ★ Master loader: weather + AQI in parallel, normalises, persists, renders |
| compareCities() | js/api.js | Geocodes two cities and fetches weather for both simultaneously |
| Search module | js/search.js | Debounced suggestions, flag icons, ↑↓/Enter/Esc keyboard navigation, recents |
| TrendChart.render() | js/charts.js | 24-hour Chart.js trend: temperature line + rain-probability bars |
| RadarMap.refresh() | js/map.js | Leaflet rain radar with animated RainViewer frames |
| renderAlerts() | js/render.js | Derives heat/UV/wind/storm/rain/AQI/visibility advisories from live data |
| applyWeatherTheme() | js/render.js | Sets body[data-wx] so ambient orbs retint to live conditions |
| init() / bootstrapLocation() | js/app.js | Entry point: restore last location → GPS → default; binds all events |
| setupInstallPrompt() | js/app.js | PWA install button via beforeinstallprompt |
CSS Architecture
Styles are pure CSS3 using custom properties (variables) for theming and a CSS Grid layout system — no preprocessor, no utility framework. Files are split by responsibility and loaded in order from index.html.
| File | Contents |
|---|---|
| css/base.css | Dark & light theme tokens, reset & typography, ambient orbs, loading screen |
| css/layout.css | App wrapper, sticky header, search bar, quick-nav, dashboard grid, footer |
| css/components.css | Hero, metrics, AQI ring, compare, forecast strips plus suggestions dropdown, alerts banner, trend chart, radar map, back-to-top |
| css/responsive.css | All @keyframes, six breakpoints, reduced-motion support, dynamic body[data-wx] weather-tint themes |
The dark theme is the default (:root) and the light theme is applied via [data-theme="light"] on the <html> element, toggled by JavaScript and persisted to localStorage.
Configuration
All user-facing configuration is centralised in the CONFIG object and static arrays at the top of js/config.js.
| Key | Type | Default | Purpose |
|---|---|---|---|
| CONFIG.isMetric | boolean | true | Temperature unit: true = °C, false = °F (persisted) |
| CONFIG.favorites | object[] | [] | Saved locations with coordinates: { id, name, label, lat, lon } |
| CONFIG.recents | object[] | [] | Last 6 searched locations, shown in the suggestions dropdown |
| CONFIG.lastLocation | object | null | Most recent location — restored instantly on next visit |
| CONFIG.maxFavorites | number | 12 | Maximum saved favorites |
| CONFIG.refreshMs | number | 900000 | Auto-refresh interval (15 minutes) |
| INDIAN_CITIES | string[] | 15 cities | Quick-access city chips in the nav bar |
| GLOBAL_CAPITALS | string[] | 30 capitals | Dropdown list of world capital cities |
To add more Indian cities or global capitals, simply append to the INDIAN_CITIES or GLOBAL_CAPITALS arrays in js/config.js.
// Example: add Siliguri to city chips const INDIAN_CITIES = [ "Kolkata", "Mumbai", ..., "Siliguri" ];
SkyCast Documentation — Built by Susovon Jana, Ph.D. · Live: sky-cast.pages.dev