🌍 earth-now.co — La planète en direct / The planet, live
earth-now.co is a real-time planetary dashboard — a robust successor to Worldometer. It displays live world metrics (population, births, CO₂, forest loss, energy, heartbeats, GDP…) that tick continuously on screen.
The fundamental difference from every other live-counter site: our counters are not opaque linear extrapolations. Every metric is driven by a documented statistical model that interpolates between the latest real observations and forecasts from authoritative sources, with seasonality and uncertainty intervals. Every number on screen is traceable: source, license, observation date, model family, confidence interval — one click away, on every counter.
✨ Core principle: a counter is a model, not a stream
We never push one value per second over the network. The server ships a CounterModel; every client animates the same pure function locally at 60 fps:
interface CounterModel {
metricId: string; // e.g. "co2_emissions_ytd"
anchorValue: number; // value at the anchor point
anchorTime: string; // ISO 8601 UTC
rateFn: RateFunction; // linear | piecewise | seasonal (Fourier) | spline (PCHIP)
uncertainty?: { low: number; high: number }; // 90 % CI
observedAt: string; // date of the last REAL observation
sourceId: string; // key in the source registry
modelVersion: string; // e.g. "seasonal-spline-v2"
displayHints: { decimals: number; sigFigs?: number; unit: string; scale?: number };
}The dashboard, the embeddable widget and the server-rendered SVG badges all evaluate the exact same function — bit-identical values, verified by a cross-runtime test (jsdom vs a spawned Node process). SSE only pushes new models (new ingestion, new forecast, correction), never per-tick values.
📊 The 76 metrics
| Domain | Count | Highlights |
|---|---|---|
| 👶 Population | 24 | World population (hero), births/deaths/net growth, human heartbeats (~9.7 B/s), top-10 countries + 6 continents ranked live |
| 💰 Economy | 9 | World GDP (~$3.7 M/s), military spending + its school-meals juxtaposition, cars, smartphones, cement, steel, e-waste, garments |
| 💧 Society | 9 | Extreme poverty, safe water, hunger, food waste, freshwater use, animals slaughtered, fish caught, coffee cups (~26 k/s), food produced |
| 🏥 Health | 7 | CVD/cancer/tobacco/malaria/child/road mortality (sober editorial rule), cigarettes smoked (~165 k/s) |
| 📱 Tech | 6 | Emails (~4.35 M/s, day+week cycles), Google searches, data created (~6.3 k TB/s), data-center electricity |
| ⚡ Energy | 5 | Electricity, renewable share, coal, oil, solar installed while you read (~19 kW/s) |
| 🌡️ Climate | 4 | CO₂ ppm (Keeling curve fit), temperature anomaly, 1.5 °C carbon budget counting down, years remaining |
| 🏭 Emissions | 3 | CO₂ YTD / today / per second |
| 🌳 Forest | 3 | Tree-cover loss YTD / today / football-pitch equivalent |
| 🌊 Ocean | 2 | Sea level rise, Arctic sea ice (strong seasonal cycle) |
| ⚡ Real-time | 2 | USGS earthquakes (true event-driven, no interpolation), humans in space |
| 🚀 Space | 2 | Earth's orbital distance (deterministic astronomy), Earth Overshoot Day countdown |
Model families in production: seasonal-ytd-v1 ×27 (Fourier day/week/year harmonics, Jan-1-UTC reset), seasonal-spline-v2 ×23 (monotone PCHIP obs/forecast fusion), derived ×13 (exact server-side compositions), linear-ytd-v1 ×8, keeling-fusion-v1 ×2 (least-squares trend + annual harmonics), static-rt-v1 ×2, linear-stock-v1 ×1.
🧪 Statistical honesty — the product
- Level 0 linear ⟶ Level 1 seasonal (Fourier/STL) ⟶ Level 2 observation/forecast fusion (monotone PCHIP splines, Kalman blending, Holt-Winters nowcasting).
- PCHIP, never natural cubic splines — a counter can mathematically never overshoot or tick backwards (property-tested with fast-check).
sigFigscaps displayed precision: world population to the unit is a lie; the ticker animates but tooltips show the honest capped value + 90 % CI.- Wide-uncertainty metrics (food waste ±15 %, garments ±30 %, AI-era estimates) always display their interval and an "estimate" label.
- Guardrails enforced at fit time: cumulative monotonicity, declared rate bounds, anchor identity, and an anti-teleportation diff that blocks deployment if a refit would visibly jump (clients smooth over 60 s instead).
- The
/methodologypage — and a per-metric method section on every/metric/<id>page — is generated from the registry: source, license, cadence, model family + version, last observation, uncertainty. A product commitment, not an option.
🗂️ Architecture
apps/
web/ # Next.js 14 (App Router) — dashboard, /metric/:id, /methodology, /embed
api/ # Fastify — REST + SSE + SVG badges + RT pollers (USGS, Open Notify)
ingest/ # Ingestion workers (USGS, NOAA CO₂; BullMQ when Redis present)
packages/
registry/ # Metric & source YAML + fixtures — the product source of truth
models/ # PCHIP, Fourier LSQ, Holt-Winters, Kalman, guardrail validation (pure)
counter/ # Shared runtime: value(model, t), formatting, windows (pure, isomorphic)
widget/ # Embeddable widget.js — IIFE, zero deps, 3.2 KB gzip (15 KB budget)
infra/ # Docker Compose, nginx, ngrok, reverse proxy, migrations, deploy scripts
scripts/ # check-headers.ts — mandatory author-header lint (runs in pnpm lint)packages/models and packages/counter are pure and deterministic: no I/O, no implicit clock — time is always a parameter. That's what makes them testable and shareable client/server.
Data flow: ingest ⟶ append-only observations ⟶ re-fit CounterModels ⟶ guardrail validation ⟶ SSE push ⟶ clients animate locally. Raw source payloads are archived with checksums so every model can be re-fitted from history.
🖥️ The frontend
- Light-first token theme (dark toggle), validated data-viz palette, overflow-proof ticking digits (
FitValuemeasures and scales — a 17-digit heartbeat counter can't break the layout on any viewport). - Live-first information architecture: a computed tier system (
secondsPerVisibleTick ≤ 2.5 s⟶ live grid, sorted fastest-first) decides what leads the page — not hand-picking. - "Since you arrived" session strip (births, deaths, CO₂, forest, orbital km, solar installed) — the catalog's signature.
- Live-ranked top-10 countries and continents with animated magnitude bars.
- Year progress meter, pulsing live indicators (tier-driven,
prefers-reduced-motionrespected), fr/en from day one, thousands separators everywhere viaIntl.NumberFormat.
🧰 Commands
pnpm dev # whole monorepo (turbo)
pnpm dev:web # frontend only
pnpm test # all packages — 142 tests
pnpm test:models # interpolators only (the critical ones)
pnpm lint # includes the mandatory file-header check
pnpm typecheck # strict TS across 10 packages
pnpm ingest:run <sourceId> # force an ingestion locally (usgs_fdsn, noaa_gml_mlo)
pnpm models:refit # re-fit + diff report with deployability verdicts
pnpm deploy:m3u96b # deploy to production + mandatory health checks✅ Testing — non-negotiable
- Golden/recovery tests for every interpolator (synthetic Keeling recovered to < 0.05 ppm; output changes without a
modelVersionbump fail CI). - Property-based tests (fast-check): cumulative monotonicity, PCHIP no-overshoot, piecewise continuity,
value(anchorTime) === anchorValue. - Client/server consistency:
counterValuein jsdom vs a separate Node process —Object.is-identical results. - Ingestion fixtures including degraded cases (truncated NOAA file, malformed USGS GeoJSON).
- Registry integration test: every declared metric must load, fit, and pass all guardrails — 0 blocked models is enforced.
🚀 Deployment
Production is exposed at https://www.earth-now.co (reverse proxy → Next.js web + Fastify API). pnpm deploy:m3u96b performs rsync → install/build on the node → process restart → mandatory health checks: GET /api/health must return 200 and /sse/health must hold an SSE stream ≥ 10 s — the deploy is not "done" until both pass. A Docker Compose stack (TimescaleDB + Redis + nginx) ships in infra/ for the DB-backed ingestion phase.
📖 Reference documents
CLAUDE.md— the full engineering contract (architecture principles, guardrails, conventions).earth-now-metrics-catalog.md— the complete metric catalog by domain with model levels, sources and priorities (🥇 MVP · 🥈 V1 · 🥉 V2+).
👤 Author
| Author | Simon-Pierre Boucher |
| Contact | contact@spboucher.ai |
| Site | www.earth-now.co |
Every source file in this repository carries the mandatory author header (enforced by scripts/check-headers.ts in CI). Data sources are credited in the UI, in API responses and on the methodology page — licenses are tracked per source in the registry, with licenseNote flags on anything requiring legal review before commercial launch.
📄 License
All rights reserved — this repository is source-available for reading and evaluation; commercial or production use requires written authorization (see LICENSE). Third-party data remains under each source's own license, documented per metric in the registry.
Chaque compteur est un modèle statistique documenté — jamais une extrapolation opaque.