Skip to content

engelde/ukrainewar

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

99 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Russo-Ukrainian War Tracker

Russo-Ukrainian War Tracker

An independent research project visualizing the Russo-Ukrainian war through interactive maps, timelines, and comprehensive conflict data.

CI License: AGPL-3.0 Next.js TypeScript Tailwind CSS Cloudflare Workers


Built to inform, not to sensationalize. This is an independent research project — not affiliated with any government, military, or news organization. It aims to provide accessible, data-driven insight into the human and material costs of the conflict.


Overview

The Russo-Ukrainian War Tracker is an independent, open-source research project that consolidates data from 15+ authoritative public sources into a single interactive experience. Users can explore territory control changes, equipment losses, casualty statistics, humanitarian impact, bilateral aid, energy infrastructure status, air defense performance, and strategic asset monitoring — all synchronized to a central timeline spanning the full duration of the war.

This project is not affiliated with any government, military organization, or news outlet. All data is sourced from publicly available APIs and datasets. The application does not generate original analysis or make claims beyond what the underlying sources report.

The entire interface is built around an explorable map rendered in muted dark tones, with data panels, counters, and visualizations layered on top. Every element is designed to put the data at the center of the experience.


Features

Interactive Map

  • Full-screen MapLibre GL vector map with dark CartoDB base tiles
  • Territory control overlays showing Russian-occupied areas over time
  • Frontline visualization tracking the contact line
  • Equipment loss markers — geotagged, categorized, and filterable by type and status
  • Conflict event clusters showing ACLED battle and violence data
  • Conflict event heatmap showing regional intensity by oblast
  • Major battle locations with historical context
  • Ukraine border and oblast boundary layers
  • Nuclear power plants — 5 Ukrainian NPPs with operational status indicators
  • Critical infrastructure — 6 dams, 4 bridges, and 9 ports
  • NATO eastern flank — 14 bases and enhanced forward presence battlegroups
  • Belarus military positions — 10 tracked entries near the Ukrainian border
  • Ukrainian military bases — 18 major installations
  • Russian military bases — 21 known positions near Ukraine
  • Energy infrastructure — gas transit pipelines and power stations
  • Troop movement arrows — 27 curated military operations with animated directional paths (cyan for Ukraine, orange for Russia)
  • NASA FIRMS thermal anomalies — near-real-time satellite fire/strike detections (VIIRS)
  • Custom canvas-drawn map icons for all infrastructure and military layers
  • All layers independently toggleable via layer controls

Central Timeline

  • Scrubable timeline spanning February 24, 2022 to present
  • Playback controls with adjustable speed (0.25x to 8x)
  • Dynamic key events from Wikidata, ACLED, GeoConfirmed (post-ACLED period), and curated editorial sources
  • Waveform visualization showing daily Russian loss intensity
  • Calendar picker for jumping to specific dates
  • URL state persistence — shareable timeline positions

Live Statistics

  • Animated counters for Russian military losses:
    • Personnel, tanks, armored vehicles, artillery systems
    • MLRS, UAVs, air defense systems, jets, helicopters
    • Ships/boats, supply vehicles
  • Sparkline trend charts showing recent daily trends
  • Data sourced from the Ukrainian Ministry of Defence
  • All statistics update dynamically during timeline playback

Event Sidebar

  • Chronological event browser with dynamic events
  • Filterable by category: Battles, Territory, Political, Military, Humanitarian, Milestones
  • Filterable by conflict events from ACLED data
  • Click-to-navigate: selecting an event jumps the timeline and map
  • Auto-tracking during timeline playback

Bilateral Aid Panel

  • Kiel Institute Ukraine Support Tracker data
  • Total aid breakdown: Military, Financial, Humanitarian (EUR billions)
  • Top donor countries ranked by total commitment (EU members highlighted)
  • Monthly allocation trends with cumulative totals
  • Top 15 weapons delivered by category

Humanitarian Panel

  • UNHCR refugee data — total refugees by year, top destination countries, IDPs
  • OCHA funding status — humanitarian appeal requirements vs. actual funding
  • Civilian casualty data — OHCHR monthly statistics by oblast
  • All humanitarian data updates during timeline playback with year-based interpolation

Equipment Loss Detail

  • Click any equipment marker for detailed information
  • Equipment type, model, status (destroyed/damaged/captured/abandoned)
  • Date, nearest location, and coordinates
  • Color-coded by status: red (destroyed), orange (damaged), green (captured), purple (abandoned)

Energy Infrastructure Panel

  • Real-time electricity generation data from the ENTSO-E Transparency Platform
  • Damaged capacity tracking — pre-war vs. current generation capacity
  • Plant-level status for thermal, nuclear, hydro, and renewable facilities
  • Gas transit monitoring — Ukrainian pipeline transit volumes via ENTSOG
  • Data updates every 6-12 hours depending on source

Air Defense Panel

  • Missile and drone attack statistics aggregated from Ukrainian Air Force reports
  • Interception rates by weapon type (cruise missiles, ballistic missiles, Shaheds)
  • Attack history — 40 curated major attack waves from February 2022 through May 2025
  • Integrated into the central timeline as filterable events

International Support Panel

  • Global alignment breakdown — 35 pro-Ukraine and 13 pro-Russia countries with proportional bar
  • Support type badges — Military, Financial, Humanitarian, Political, Sanctions, Troops
  • Aid totals per country and combined
  • Country details with notable contributions and descriptions
  • Data sourced from Kiel Institute and open records

Ukrainian Losses Panel

  • Casualty estimates compiled from multiple independent sources
  • Mediazona confirmed — verified deaths by name (conservative minimum)
  • Western intelligence — US, UK, and EU assessment figures
  • OHCHR civilian casualties — UN-verified minimum
  • Clear disclaimers about data uncertainty and methodology differences

Sanctions Panel

  • 27 curated sanctions packages across EU (14), US (6), UK (3), Canada, Japan, Australia, Switzerland
  • Summary statistics — total packages, individuals, and entities sanctioned
  • Imposer breakdown — color-coded bar chart by sanctioning body
  • Key measures — 10 major bans (SWIFT, oil embargo, price cap, diamond ban, etc.)
  • Timeline-aware — filters to show only sanctions imposed by the selected date
  • Data sourced from EU Council, US Treasury OFAC, UK Government

URL State Management

  • Timeline date, map position (lat/lng/zoom), and sidebar state persisted in URL
  • Every view is shareable and bookmarkable via nuqs

Tech Stack

Category Technology
Framework Next.js 16 (App Router)
Language TypeScript 5
UI Library React 19
Styling Tailwind CSS 4
Components shadcn/ui
Maps MapLibre GL
Icons react-icons (Tabler + Game Icons)
URL State nuqs
Fonts DM Sans + DM Mono
Linting Biome
Git Hooks Husky + commitlint
Versioning Release Please
Deployment Cloudflare Workers via OpenNextJS

API Routes

The application exposes the following API endpoints. All responses are cached with stale-while-refresh semantics.

Route Description Cache
/api/losses Russian equipment and personnel losses (MoD) 1h
/api/losses/recent Recent visually confirmed losses (WarSpotting) 6h
/api/casualties Civilian casualty data (OHCHR via HDX) 4h
/api/territory Territory control GeoJSON (DeepState) 12h
/api/events Key events (Wikidata SPARQL + curated) 24h
/api/acled Conflict events (ACLED) 24h
/api/refugees Refugee and IDP statistics (UNHCR) 24h
/api/humanitarian Funding appeal data (OCHA via HDX) 24h
/api/aid Bilateral aid commitments (Kiel Institute) 7d
/api/firms NASA FIRMS thermal anomalies (VIIRS satellite) 3h
/api/energy Electricity generation + plant status (ENTSO-E) 6h
/api/energy/gas Gas transit through Ukraine (ENTSOG) 12h

Data Sources

This project aggregates data from the following authoritative sources. All data is accessed through publicly available APIs and datasets. This is an independent research effort — the project is not endorsed by or affiliated with any of these sources.

Source Data Provided Link
WarSpotting Visually confirmed Russian equipment losses with geolocation warspotting.net
Ukrainian Ministry of Defence Official daily personnel and equipment loss reports mil.gov.ua
Ukrainian Air Force Missile and drone attack reports, interception statistics t.me/kpszsu
DeepState Map Territory control and frontline GeoJSON data deepstatemap.live
ACLED Armed conflict event data — battles, civilian targeting, protests acleddata.com
Wikidata Structured data on named events, battles, and offensives (via SPARQL) wikidata.org
GeoConfirmed OSINT photo/video-verified geolocated events (used to fill the post-ACLED gap) geoconfirmed.org
HDX / OCHA Humanitarian response data, funding status data.humdata.org
OHCHR UN-verified civilian casualty statistics ohchr.org
UNHCR Refugee and internally displaced persons statistics data.unhcr.org
Kiel Institute Ukraine Support Tracker — bilateral military, financial, and humanitarian aid ifw-kiel.de
Mediazona / BBC Confirmed-by-name Ukrainian casualty investigations zona.media
VIINA Territorial control derived from news coverage (Zhukov & Ayers) github.com/zhukovyuri/VIINA
NASA FIRMS Near-real-time satellite thermal anomaly detections (VIIRS) firms.modaps.eosdis.nasa.gov
ENTSO-E European electricity generation data (Transparency Platform) transparency.entsoe.eu
ENTSOG European gas transit flow data (Transparency Platform) transparency.entsog.eu
Sanctions data Curated from EU Council, US Treasury OFAC, UK Government sanctions lists Various official sources
Wikipedia Pre-invasion order of battle, force groupings, and buildup timeline en.wikipedia.org
CSIS Invasion axis analysis and satellite imagery assessment csis.org

Data Freshness

All API responses use a multi-layer persistent caching system (file-based in development, Cloudflare KV in production) with stale-while-refresh semantics. A Cloudflare Worker cron runs every 6 hours to pre-warm all caches.

Dataset Cache Duration Update Frequency
Equipment stats 1 hour Hourly
Recent losses 6 hours Multiple times daily
Casualty reports 4 hours Daily
Territory control 12 hours Daily
Conflict events (ACLED) 24 hours Daily
GeoConfirmed events 24 hours Daily (post-ACLED gap fill)
NASA FIRMS thermal anomalies 3 hours Near-real-time
Electricity generation (ENTSO-E) 6 hours Hourly
Gas transit (ENTSOG) 12 hours Daily
Key events (Wikidata) 24 hours Community-edited
Refugee/IDP data 24 hours Monthly
Humanitarian funding 24 hours Monthly
Civilian casualties 24 hours Monthly (OHCHR)
Bilateral aid 7 days Monthly releases
VIINA territory Weekly Weekly snapshots
Missile attack dataset Static Curated (40 major waves)
Sanctions data 7 days Curated (static, updated with new packages)
Pre-invasion mobilization Static Curated historical dataset (Mar 2021 – Feb 2022)

Methodology

This project does not generate original analysis. Instead, it consolidates, cross-references, and visualizes data from the sources listed above. Below is how each major data domain is constructed.

Territory Control & Frontline

Territory control is shown in two phases. From February 2022 through mid-2023, the VIINA dataset (Zhukov & Ayers, University of Michigan) provides weekly territorial control estimates derived from systematic monitoring of news reports from multiple Ukrainian and Russian outlets. The application converts VIINA's point-level observations into filled polygons using convex hull computation and Delaunay triangulation to approximate areas of control, and derives frontline geometry by walking the boundary between Russian-controlled and Ukrainian-controlled clusters. From mid-2023 onward, the DeepState Map provides higher-resolution daily GeoJSON polygons for both occupied territory and the frontline. The transition between sources is handled automatically based on the selected timeline date.

Russian Equipment Losses

Daily aggregate loss figures (personnel, tanks, armored vehicles, artillery, etc.) come from the Ukrainian Ministry of Defence's official reports. These are displayed as animated counters with sparkline trend charts. Individual geolocated equipment losses are sourced from WarSpotting, which catalogs visually confirmed losses from open-source imagery. Each loss is categorized by type, status (destroyed, damaged, captured, abandoned), and mapped to its confirmed location.

Ukrainian Losses

Ukrainian military casualties are sourced exclusively from the Mediazona/BBC News Russian Service investigation, which identifies fallen soldiers by name through obituaries, social media, and official records. Only confirmed-by-name figures are shown. The application does not display estimates or extrapolations. A disclaimer explains this methodology and notes that actual losses are likely significantly higher than the confirmed count.

Civilian Casualties & Humanitarian Data

Civilian casualty figures come from the UN Office of the High Commissioner for Human Rights (OHCHR), which publishes verified monthly reports. Refugee and internally displaced persons statistics come from UNHCR. Humanitarian funding data — including the UN Flash Appeal and Refugee Response Plan — comes from OCHA's Humanitarian Data Exchange (HDX). All figures are presented as reported by these organizations without modification.

Bilateral Aid

Military, financial, and humanitarian aid commitments to Ukraine are sourced from the Kiel Institute for the World Economy's Ukraine Support Tracker, which publishes structured datasets tracking bilateral aid by country, type, and amount. The International Support panel aggregates this data by donor country and support category.

Conflict Events

Battle locations, civilian targeting events, and protests are sourced from the Armed Conflict Location & Event Data Project (ACLED), which provides georeferenced event data updated daily. These are displayed as clustered points and heatmap overlays. Major named events shown in the timeline and event sidebar are sourced from Wikidata SPARQL queries filtered to the Russo-Ukrainian War, supplemented by curated editorial additions for events not yet reflected in Wikidata.

Energy Infrastructure

The Energy panel combines data from the ENTSO-E Transparency Platform (European electricity generation data) with a curated dataset of Ukrainian power plants and their wartime damage status. Historical energy snapshots are computed by tracking known strike dates against each facility. Gas pipeline status is derived from ENTSOG flow data and curated records of the Russia-Ukraine transit shutdown (January 2025) and TurkStream operations.

Infrastructure Status

Critical infrastructure — including dams, bridges, ports, nuclear plants, and thermal power plants — is tracked using a curated dataset with timestamped status changes. Each item's status (operational, damaged, destroyed, occupied) is computed relative to the selected timeline date using documented events. Nuclear plant data is cross-referenced with IAEA monitoring reports.

Air Defense Performance

Missile and drone attack data is curated from Ukrainian Air Force command reports, tracking interception rates by weapon type (cruise missiles, ballistic missiles, Shahed drones, guided bombs). Each major attack wave is logged with totals launched, intercepted, and the resulting interception percentage.

Sanctions

Sanctions data is curated from official published lists including EU Council regulations, US Treasury OFAC designations, and UK Government sanctions. The timeline tracks when each major sanctions package was adopted and what categories of restrictions it imposed.

Thermal Anomalies

Near-real-time fire and explosion detections come from NASA's Fire Information for Resource Management System (FIRMS), which provides satellite-detected thermal anomalies from the VIIRS instrument. These are displayed as map markers showing active fires and potential strike impacts.

Pre-Invasion Mobilization

The buildup layer visualizes the Russian military mobilization that preceded the full-scale invasion (March 2021 – February 2022). This data is curated from multiple open-source intelligence references since no single structured API exists for this historical period. Force grouping locations, troop estimates, battalion tactical group (BTG) counts, and equipment compositions are compiled from:

  • Wikipedia Order of Battle — Structured table of 9 force groupings with staging locations, BTG counts, and parent army units
  • Wikipedia "Prelude to the 2022 Russian invasion" — Timeline of troop movements and buildup milestones
  • CSIS "Russia's Possible Invasion of Ukraine" (Jan 2022) — Analysis of three planned invasion axes with satellite imagery locations
  • Zapad 2021 Exercise Documentation — 200,000-troop joint Russia-Belarus exercise across 14 training grounds
  • IISS Military Balance 2022 — Force structure and equipment inventory reference data

All troop and equipment numbers shown are consensus estimates from open-source intelligence, not verified counts. The buildup is presented in three phases: Phase 1 (March–April 2021, initial deployment), Zapad 2021 (September 2021, joint exercise), and Phase 2 (October 2021–February 2022, final invasion positioning).


Getting Started

Prerequisites

Installation

git clone https://github.com/engelde/ukrainewar.git
cd ukrainewar
npm install

Environment Variables

Copy .env.example to .env.local and fill in the required values:

cp .env.example .env.local
Variable Required Description
ACLED_EMAIL Yes ACLED API email — register here
ACLED_PASSWORD Yes ACLED API password
ENTSOE_TOKEN No ENTSO-E Transparency Platform API token for energy data
NASA_FIRMS_KEY No NASA FIRMS API key for thermal anomaly detection (falls back to demo key)
CACHE_REFRESH_SECRET Yes Shared secret for the /api/cache/refresh endpoint used by the cron worker

For Cloudflare Workers deployment, set secrets via Wrangler:

wrangler secret put ACLED_EMAIL
wrangler secret put ACLED_PASSWORD
wrangler secret put CACHE_REFRESH_SECRET

Development

npm run dev

Open http://localhost:3000 to view the application.

Available Scripts

Script Description
npm run dev Start development server (Turbopack)
npm run build Production build
npm run lint Run Biome linter
npm run lint:fix Auto-fix linting issues
npm run format Format code with Biome
npm run typecheck TypeScript type checking
npm run cache:warm Pre-warm persistent caches (ACLED data)
npm run data:update Process all static data sources
npm run build:worker Build for Cloudflare Workers
npm run deploy Deploy to Cloudflare Workers
npm run deploy:cron Deploy the data-refresh cron worker

Deployment

The application is deployed to Cloudflare Workers using OpenNextJS Cloudflare.

Cloudflare KV Setup

Create a KV namespace for the persistent cache layer:

wrangler kv:namespace create "CACHE"

Copy the returned namespace ID and update wrangler.jsonc:

"kv_namespaces": [
  {
    "binding": "CACHE",
    "id": "<your-kv-namespace-id>"
  }
]

Deploy

npm run build:worker
npm run deploy

A separate Cloudflare Worker handles scheduled data refresh via cron triggers (every 6 hours), pre-warming all API caches.

npm run deploy:cron

Contributing

Contributions are welcome. Please note:

  1. This project uses conventional commits enforced by commitlint
  2. All code is linted and formatted by Biome (pre-commit hook)
  3. PRs must pass CI checks (lint, typecheck, build)
# Example commit
git commit -m "feat: add population displacement chart"

# Commit types: feat, fix, docs, style, refactor, perf, test, build, ci, chore

Methodology

This project aggregates, cross-references, and visualizes publicly available conflict data. It does not generate original analysis or make claims beyond what the underlying sources report.

  • Russian military losses are displayed from the Ukrainian Ministry of Defence daily reports. These are official claims and may differ from independently verified counts. WarSpotting data provides a separate, OSINT-verified count that is typically 30–50% of official figures — both are displayed with clear source attribution.
  • Ukrainian military losses are not officially published by Ukraine. Estimates are compiled from Mediazona/BBC confirmed-by-name investigations (conservative minimums), Western intelligence assessments (US, UK, EU), and partial official disclosures. All estimates are presented with source attribution and uncertainty disclaimers.
  • Territory control is derived from DeepState Map's daily GeoJSON releases, with coverage from July 2024 onward. Earlier periods use VIINA territorial assessments where available.
  • Conflict events are sourced from ACLED's geocoded event database, filtered for events with 5+ fatalities. Key events combine Wikidata SPARQL queries with curated editorial selections for political and diplomatic milestones.
  • Humanitarian data comes from UNHCR (refugees/IDPs), OCHA (funding appeals), and OHCHR (civilian casualties). Refugee and IDP figures are available as yearly snapshots; civilian casualties are monthly.
  • Bilateral aid data is from the Kiel Institute's Ukraine Support Tracker, which tracks committed and disbursed military, financial, and humanitarian aid from 41 donor countries.
  • Energy infrastructure data combines ENTSO-E electricity generation figures with curated plant-level status information. Gas transit volumes are sourced from ENTSOG's Transparency Platform, filtered for Ukrainian interconnection points.
  • Thermal anomaly detections are sourced from NASA FIRMS using the VIIRS satellite instrument. Detections are filtered to the conflict zone and displayed as potential fire/strike indicators — not all detections represent military activity.
  • Missile attack data is compiled from Ukrainian Air Force daily reports. The dataset includes 40 curated major attack waves from February 2022 through May 2025, with weapon types, quantities launched, and interception counts.
  • Strategic asset positions (nuclear plants, dams, bridges, ports, NATO bases, Belarus military positions, Ukrainian and Russian bases) are sourced from curated geospatial datasets and updated as conditions change.
  • International support alignment data tracks 48 countries across both sides, with aid figures sourced from the Kiel Institute's Ukraine Support Tracker and open records.

Data Limitations

  • OHCHR civilian casualty figures are considered conservative minimums — actual figures are likely higher
  • Ukrainian military casualty estimates vary widely between sources (Mediazona confirms ~43,000 by name; Western intelligence suggests ~100,000). No single figure is definitive
  • ACLED free-tier access has a 12-month recency restriction; older data may be limited
  • Territory GeoJSON is only available from July 2024; earlier frontline positions are approximated
  • Equipment loss markers only appear where geolocation data is available (a subset of confirmed losses)
  • Refugee and IDP data updates yearly, not monthly — during timeline playback, the most recent available year's figures are shown
  • Humanitarian funding data reflects UN-coordinated appeals only, not total global aid
  • NASA FIRMS thermal detections include non-conflict sources (e.g., agricultural fires, industrial activity); not all anomalies indicate military strikes
  • ENTSO-E generation data reflects grid-connected output only and may not capture off-grid or emergency generation
  • Missile attack interception rates are based on Ukrainian Air Force claims, which may differ from independent assessments
  • Strategic asset positions (NATO, Belarus) are based on publicly reported information and may not reflect all deployments

Attribution

Created and maintained by David Engel

This is an independent, open-source research project. It is not affiliated with, endorsed by, or funded by any government, military organization, or news outlet. The project exists to make publicly available conflict data more accessible and understandable.

This project relies on publicly available data from the sources listed above. Each data source retains its own licensing terms. The ACLED dataset is used under CC-BY 4.0. Kiel Institute data is from the publicly available Ukraine Support Tracker. UNHCR and OCHA data are provided through their respective open data portals. NASA FIRMS data is freely available under NASA's open data policy. ENTSO-E and ENTSOG data are accessed through their public Transparency Platforms.

If you use this project in academic work, please cite:

Engel, D. (2026). Russo-Ukrainian War Tracker [Web application].
https://ukrainewar.app. Source code: https://github.com/engelde/ukrainewar

License

This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0).

This means you are free to:

  • Use — run the application for any purpose
  • Study — read and learn from the source code
  • Modify — adapt and build upon this work
  • Share — distribute copies

Under the following conditions:

  • Source disclosure — if you deploy a modified version, you must make the source code available
  • Same license — derivative works must be licensed under AGPL-3.0
  • Attribution — you must give appropriate credit

See LICENSE.txt for the full license text.


ukrainewar.app · Built with data, designed for understanding.

This project is an independent effort and is not affiliated with any government or military organization.

About

Real-time Russo-Ukrainian War Tracker — interactive maps, timelines, and conflict data visualization (https://ukrainewar.app)

Resources

License

Stars

Watchers

Forks

Contributors