A production-grade, full-stack weather platform that fuses data from multiple live APIs, applies a custom intelligence layer, and delivers a premium glassmorphism UI with real-time environmental insights.
- 📚 Documentation (Beginner-Friendly)
- Overview
- Live Demo
- Screenshots & Preview
- Key Features
- Architecture
- Intelligence Engines
- Project Structure
- API Endpoints
- Tech Stack
- Getting Started
- Environment Variables
- Deployment
- Responsive Design
- How Data Flows
- License
New to this project? Start here. The
docs/folder contains a complete beginner-friendly guide to every part of SkyGlass — written in plain English with real-life analogies. No prior coding knowledge assumed.
| # | File | What You Will Learn |
|---|---|---|
| 1 | 01 — Big Picture | What problem SkyGlass solves and why it matters |
| 2 | 02 — Full Flow | The complete story: search → servers → engines → dashboard |
| 3 | 03 — Engines Explained | All 12 intelligence engines, one-by-one with analogies |
| 4 | 04 — Features Explained | APIs, caching, rate limiting, API key security |
| 5 | 05 — Code Walkthrough | Every important file's code explained line-by-line |
| 6 | 06 — Real Examples | Mumbai, Delhi, London — watch the system think |
| 7 | 07 — Why Better | 14-point comparison vs ordinary weather apps |
| 8 | 08 — Viva Summary | Quick-memorize tables, formulas, and key points |
| 9 | 09 — Viva Q&A | 10 likely teacher questions + detailed model answers |
| 10 | 10 — Glossary | Every technical term explained in plain English (A–Z) |
| — | Master Index | Full docs map + 30-second pitch |
SkyGlass is not a typical weather widget. It is a multi-source environmental intelligence system built from scratch with a decoupled frontend/backend architecture. Instead of blindly trusting a single weather provider, SkyGlass simultaneously queries WeatherAPI and Open-Meteo, fuses the results through a custom normalization engine, applies an eight-step intelligence pipeline, and finally serves a clean, unified JSON response to the frontend.
The result is a dashboard that provides not only current conditions but also:
- Next-hour predictions via trend extrapolation
- Rain probability scoring from atmospheric composites
- Anomaly detection for extreme or dangerous conditions
- Atmospheric stability classification
- AQI health guidance with real-time air quality data
- 7-day blended forecast combining both data sources
- 14-day historical view with interactive charts
| Platform | URL | Notes |
|---|---|---|
| ⚫ Vercel ⭐ | weather-app-by-saptarshi-sadhu.vercel.app | Primary deployment — fastest, global CDN, always on |
| 🟣 Render | weather-app-bfqr.onrender.com | Full-stack Node.js service (may cold-start on free tier) |
| 🐙 Source Code | github.com/SAPTARSHI-coder/Weather-App | Full source — open for contributions |
⭐ Recommended: Use the Vercel link for the best experience — it is the primary, production-grade deployment with zero cold-start latency and global edge delivery.
Full glassmorphism dashboard showing live weather data for Los Angeles — featuring the current conditions hero card, AQI panel, wind compass, humidity indicator, sunrise/sunset card, and the sidebar navigation.
End-to-end walkthrough: city search → real-time data load → forecast strips → intelligence panel → interactive radar map.
| Feature | Details |
|---|---|
| 🔀 Data Fusion | Blends WeatherAPI (primary) + Open-Meteo (secondary) into a single canonical snapshot |
| 🧠 Prediction Engine | Extrapolates next-hour temperature & condition from historical trend slopes |
| 🌧️ Rain Scoring | Multi-factor rain probability: humidity, cloud cover, pressure trend, visibility, precipitation |
| ⚡ Anomaly Detection | Flags statistically extreme events (heatwaves, pressure crashes, zero visibility) |
| 🌿 AQI Intelligence | Real-time Air Quality Index with health tips and color-coded risk categories |
| 🌡️ RealFeel® Temperature | AccuWeather-style perceived temperature accounting for wind, humidity, and UV |
| 📈 Trend Engine | Per-city in-memory ring buffer tracking temperature, humidity, pressure, AQI slopes |
| 🗺️ Interactive Map | Leaflet.js map with toggleable RainViewer (Precipitation Radar) and OpenWeatherMap (Satellite Clouds) overlays |
| 📅 History Dashboard | 14-day lookback with Chart.js visualizations (temperature, humidity, pressure, AQI) |
| ⏱️ Dual Timezone Clock | Live clock widget showing local time and a second configurable timezone |
| 💨 Atmosphere Monitor | Dedicated pressure, UV, and CO monitoring cards |
| 🔒 Secure Key Management | API keys never touch the browser — all external requests route through the backend |
| ⚡ 5-min Response Cache | In-memory TTL cache on the server reduces redundant API calls |
| 🔁 Retry + Timeout Logic | fetchWithRetry() wrapper with configurable retries and axios timeouts |
| 📱 Responsive Design | Mobile-first glassmorphism UI with smooth CSS animations and micro-interactions |
┌─────────────────────────────────────────────────────────────────────┐
│ BROWSER (Frontend) │
│ index.html · style.css · script.js · mapUtils.js │
│ Leaflet.js (Map) · Chart.js (Graphs) │
└─────────────────────────┬───────────────────────────────────────────┘
│ HTTP GET /api/weather?lat=&lon=
▼
┌─────────────────────────────────────────────────────────────────────┐
│ Express Server (server.js) │
│ │
│ ┌──────────────┐ ┌──────────────────────────────────────────┐ │
│ │ In-Memory │ │ 8-Step Intelligence Pipeline │ │
│ │ TTL Cache │ │ 1. Normalize 5. RealFeel │ │
│ │ (5 min TTL) │ │ 2. Fuse 6. AQI │ │
│ └──────────────┘ │ 3. Condition 7. Confidence │ │
│ │ 4. Smoothing 8. Intelligence Layer │ │
│ └──────────────────────────────────────────┘ │
└────────┬──────────────────────────────────────────┬─────────────────┘
│ │
▼ ▼
┌────────────────────┐ ┌────────────────────────────┐
│ WeatherAPI.com │ │ Open-Meteo.com │
│ (Current + 3-day │ │ (Hourly + 7-day forecast, │
│ forecast + AQI) │ │ free, no key required) │
└────────────────────┘ └────────────────────────────┘
All engines live in src/weatherEngine/. Each is a standalone ES module with a single responsibility.
| Engine | File | Purpose |
|---|---|---|
| Normalizer | normalizer.js |
Converts raw WeatherAPI and Open-Meteo responses into a shared canonical schema |
| Fusion Engine | fusionEngine.js |
Merges two normalized snapshots using weighted averaging and tracks sources_used |
| Condition Engine | conditionEngine.js |
Derives a semantic weather condition string and emoji from fused data; maps to icon |
| RealFeel Engine | realFeelEngine.js |
Computes perceived temperature using wind chill, heat index, and UV adjustment formulas |
| AQI Handler | aqiHandler.js |
Resolves raw air quality readings to a scalar AQI, categorizes it, and outputs health tips |
| Confidence Calculator | confidenceCalc.js |
Scores data confidence (High/Medium/Low) based on source count and inter-source temp delta |
| Trend Engine | trendEngine.js |
Maintains a per-city rolling ring buffer; computes linear regression slopes for temp, humidity, pressure, AQI |
| Prediction Engine | predictionEngine.js |
Projects next-hour temp and condition from trend slopes and current state |
| Rain Engine | rainEngine.js |
Calculates rain probability (0–100%) from humidity, pressure trend, cloud, visibility, and precip |
| Anomaly Engine | anomalyEngine.js |
Detects statistical outliers (extreme heat/cold, pressure crashes, dangerous AQI, near-zero visibility) |
| Stability Engine | stabilityEngine.js |
Classifies atmospheric stability (Stable / Unsettled / Volatile) using temp variance in the ring buffer |
| Insight Engine | insightEngine.js |
Generates a prioritized list of natural-language environmental insight strings for the dashboard |
skyglass-weather/
│
├── index.html # Main SPA shell — all dashboard cards, modals, map container
├── style.css # Global design system: glassmorphism, animations, responsive grid
├── script.js # Frontend brain: event handling, API calls, DOM updates, charts
├── mapUtils.js # Leaflet map initialization, weather tile overlay, click-to-search
├── storageUtils.js # LocalStorage helpers for persisting user preferences
├── prepend.js # Utility run before Vite build (meta injection, etc.)
│
├── server.js # Express backend: API proxy, fusion pipeline, cache, endpoints
├── vite.config.js # Vite build configuration
├── package.json # Dependencies and npm scripts
├── .env # Secret environment variables (not committed)
├── .gitignore
│
├── src/
│ └── weatherEngine/ # 12 standalone intelligence engine modules
│ ├── normalizer.js
│ ├── fusionEngine.js
│ ├── conditionEngine.js
│ ├── realFeelEngine.js
│ ├── aqiHandler.js
│ ├── confidenceCalc.js
│ ├── trendEngine.js
│ ├── predictionEngine.js
│ ├── rainEngine.js
│ ├── anomalyEngine.js
│ ├── stabilityEngine.js
│ └── insightEngine.js
│
├── public/ # Static assets (icons, images)
├── dist/ # Production build output (generated by `npm run build`)
└── docs/ # 📚 Full beginner documentation (11 files)
├── 00_index.md # Master index
├── 01_big_picture.md
├── 02_full_flow.md
├── 03_engines_explained.md
├── 04_features_explained.md
├── 05_code_walkthrough.md
├── 06_examples.md
├── 07_why_better.md
├── 08_viva_summary.md
├── 09_viva_questions.md
├── 10_glossary.md
└── PROJECT_OVERVIEW.md # Full original technical reference
The Express backend exposes three REST endpoints:
The primary fusion endpoint. Returns the full intelligence payload for a location.
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
lat |
number |
Yes* | Latitude of the location |
lon |
number |
Yes* | Longitude of the location |
q |
string |
Yes* | City name or lat,lon string (alternative to lat/lon) |
*Either lat+lon or q must be provided.
Response Fields (abbreviated):
{
"success": true,
"data": {
"temp": 24,
"feels_like": 26,
"feels_like_desc": "Warm",
"humidity": 68,
"wind_kph": 14.4,
"wind_dir": "SSW",
"cloud": 40,
"visibility": 10,
"uv": 5,
"is_day": 1,
"precip_mm": 0,
"pressure_mb": 1013,
"condition": "Partly Cloudy",
"condition_emoji": "⛅",
"condition_icon": "cloud-sun",
"aqi": 45,
"aqi_category": "Good",
"aqi_color": "#00c853",
"aqi_emoji": "🟢",
"aqi_tip": "Air quality is satisfactory.",
"confidence": 90,
"confidence_label": "High",
"sources_used": ["WeatherAPI", "Open-Meteo"],
"city": "Mumbai",
"country": "India",
"forecast7": [ /* 7-day blended forecast array */ ],
"predicted_temp": 25,
"predicted_condition": "Partly Cloudy",
"temp_direction": "rising",
"rain_probability": 32,
"stability": "Stable",
"anomalies": [],
"anomaly_severity": "none",
"insights": ["Moderate UV — wear sunscreen outdoors."],
"trends": { "temp_trend": 0.3, "pressure_trend": -0.1 },
"raw": { /* full WeatherAPI response */ }
}
}Fetches historical weather data for a specific date via WeatherAPI.
| Parameter | Type | Required | Description |
|---|---|---|---|
q |
string |
Yes | City name or coordinates |
dt |
string |
Yes | Date in YYYY-MM-DD format |
City autocomplete search powered by WeatherAPI's search endpoint.
| Parameter | Type | Required | Description |
|---|---|---|---|
q |
string |
Yes | Partial city name to search |
Backend
| Package | Version | Role |
|---|---|---|
express |
^5.2.1 | HTTP server framework |
axios |
^1.13.2 | HTTP client for external API calls |
dotenv |
^17.2.3 | Environment variable injection |
cors |
^2.8.5 | Cross-Origin Resource Sharing middleware |
Frontend
| Library | Version | Role |
|---|---|---|
chart.js |
^4.4.0 | Historical data visualizations |
chartjs-plugin-datalabels |
^2.2.0 | Value labels on chart bars |
leaflet |
^1.9.4 | Interactive map with weather tile overlays |
Tooling
| Tool | Version | Role |
|---|---|---|
vite |
^6.0.0 | Frontend build tool and dev server |
External APIs
| API | Key Required | Usage |
|---|---|---|
| WeatherAPI.com | ✅ Yes | Current weather, 3-day forecast, AQI, search, history |
| OpenWeatherMap | ✅ Yes | Satellite cloud cover tile overlays for the map |
| Open-Meteo.com | ❌ No | 7-day extended forecast, hourly data (free) |
- Node.js v18 or higher
- A free WeatherAPI key from weatherapi.com
git clone https://github.com/SAPTARSHI-coder/Weather-App.git
cd Weather-Appnpm installCreate a .env file in the project root:
WEATHER_API_KEY=your_weatherapi_key_here
VITE_OWM_API_KEY=your_openweathermap_key_here
PORT=3001This starts both the Express backend and the Vite dev server concurrently:
npm run dev- Frontend (Vite):
http://localhost:5173 - Backend (Express):
http://localhost:3001
npm run buildThen start the production server (serves the built frontend as static files):
node server.js| Variable | Required | Description |
|---|---|---|
WEATHER_API_KEY |
✅ Yes | WeatherAPI.com API key for core data |
VITE_OWM_API_KEY |
✅ Yes | OpenWeatherMap API key for map cloud tiles |
PORT |
No | Server port (defaults to 3001) |
⚠️ Never commit your.envfile. It is already listed in.gitignore. API keys should be set as environment variables in your hosting dashboard (e.g., Render's Environment tab).
SkyGlass is deployed on two platforms simultaneously:
Live: https://weather-app-by-saptarshi-sadhu.vercel.app
Vercel is the recommended and primary hosting platform for SkyGlass. It provides zero-configuration deployment, global edge CDN, instant cache invalidation, and automatic HTTPS — with zero cold-start delays.
| Setting | Value |
|---|---|
| Framework Preset | Vite |
| Build Command | npm run build |
| Output Directory | dist |
| Node Version | 18.x+ |
Vercel automatically detects the Vite configuration and optimises the build for global edge delivery.
Live: https://weather-app-bfqr.onrender.com
The Render deployment runs the complete Express + Vite stack as a single Node.js service. Note that the free tier may exhibit a cold-start delay of ~30 s after periods of inactivity.
| Setting | Value |
|---|---|
| Build Command | npm install && npm run build |
| Start Command | npm start |
| Environment | Node |
| Port | 10000 (Render default) or set via PORT env var |
Set the following in Render → Your Service → Environment:
WEATHER_API_KEY = your_weatherapi_key_here
VITE_OWM_API_KEY = your_openweathermap_key_here
The Express server in server.js is automatically configured to serve the built dist/ folder as static files in production, so a single backend service handles both serving the frontend and running the backend API seamlessly.
SkyGlass is fully responsive across all screen sizes, implemented with CSS media queries in style.css. No external responsive framework is used — all breakpoints are hand-crafted with vanilla CSS.
| Breakpoint | Target | Key Behaviour |
|---|---|---|
≥ 1200px |
Desktop (full) | Full three-column dashboard grid, side-by-side forecast panels |
≤ 1200px |
Laptop / small desktop | Forecast panels stack to a single column; intel grid collapses to 2 columns |
≤ 1100px |
Wide tablet | Intelligence panel grid collapses from 4 → 2 columns |
≤ 900px |
Tablet / large mobile | Sidebar slides off-screen (hamburger menu); dashboard grid becomes single-column; margin-left removed from .main-content |
≤ 768px |
Tablet (portrait) | Reduced padding and font sizes; search bar takes full width; header stacks vertically; clock widget repositioned |
≤ 650px |
Mobile (large) | Intelligence panel collapses to full single-column; horizontal borders replace vertical dividers |
≤ 480px |
Mobile (small) | Compact typography, compressed cards, hidden non-critical map legend labels |
- Sidebar: Fixed 250 px sidebar on desktop → slides off-screen (
left: -100%) at≤ 900pxwith a hamburger toggle button revealed - Dashboard Grid: 3-column (
2fr 1fr 1fr) on desktop → single column on mobile - Forecast Grid: 2-column side-by-side on desktop → stacked single column at
≤ 1200px - Intelligence Panel: 4-column horizontal strip → 2-column at
≤ 1100px→ single column at≤ 650px - Charts:
overflow-x: autowithmin-width: 400pxcanvas ensures charts remain readable and horizontally scroll on narrow viewports - Typography: Heading and value font sizes scale down progressively at smaller breakpoints
- Map: Full-height interactive map adapts height to available viewport on small screens
1. User searches for a city or grants geolocation
│
▼
2. Frontend (script.js) sends GET /api/weather?lat=&lon= to the backend
│
▼
3. Server checks the 5-minute in-memory TTL cache
├── HIT → return cached response instantly
└── MISS → continue pipeline
│
▼
4. PARALLEL fetch:
├── WeatherAPI → current + 3-day forecast + AQI
└── Open-Meteo → hourly + 7-day forecast (via resolved coordinates)
│
▼
5. Normalize both API responses into canonical weather snapshots
│
▼
6. Fuse snapshots → weighted average of temp, humidity, wind, etc.
│
▼
7. Intelligence pipeline (all computed server-side):
├── Condition Engine → semantic label + emoji + icon
├── RealFeel Engine → perceived temperature
├── Data Smoothing → EMA smoothing to reduce noise
├── AQI Handler → scalar AQI + category + health tip
├── Confidence Calc → reliability score + reason
├── Trend Engine → store snapshot; compute slopes
├── Prediction Engine → next-hour temp + condition
├── Rain Engine → multi-factor probability score
├── Anomaly Engine → flag dangerous outliers
├── Stability Engine → classify atmospheric turbulence
└── Insight Engine → generate human-readable alerts
│
▼
8. Assemble final JSON, cache it, send to frontend
│
▼
9. Frontend renders: cards, charts, map, forecast strips, insight panel
This project is open source and available under the MIT License.
SkyGlass — See beyond the forecast.

