DEV Community

johnsmalls22-rgb
johnsmalls22-rgb

Posted on

How I Track Every Ship in the Strait of Hormuz in Real Time

21 million barrels of oil pass through the Strait of Hormuz every day. I built a real-time intelligence dashboard that tracks every vessel, detects dark ships, and monitors the crisis.

Live Demo | GitHub

Why I Built This

During the 2019 tanker attacks, I realized there was no public tool combining vessel tracking, oil prices, and naval positions. Analysts were switching between MarineTraffic, Bloomberg, and USNI Fleet Tracker. I wanted one dashboard.

What It Tracks

  • 88+ vessels via AIS — updated every 5 seconds
  • Dark ships — vessels with disabled transponders
  • Brent and WTI oil prices — 90-day history (EIA + FRED)
  • Daily transit counts — IMF PortWatch data
  • 10 US Navy carriers — positions via GDELT/USNI
  • 7-day maritime weather — wind warnings
  • Breaking news — Google News RSS

Tech Stack

  • Next.js 16 + React 19
  • Mapbox GL JS with custom GeoJSON layers
  • Recharts for charts
  • Tailwind CSS 4
  • TypeScript

Dark Ship Detection

Some vessels disable AIS transponders. My approach:

  1. Detect when a vessel stops broadcasting (last timestamp > 2 hours)
  2. Estimate position based on last known course and shipping lane geometry
  3. Render estimates along the Traffic Separation Scheme centerline
  4. Show uncertainty visually

The shipping lane centerline is the key insight. The strait has well-defined inbound and outbound lanes. Dark ships are almost certainly in this corridor.

Water Polygon Filter

GPS drift places 10-15% of vessels on land. I built a 40-vertex polygon tracing the Gulf coastline:

function isInWater(lat: number, lon: number): boolean {
  let inside = false;
  for (let i = 0, j = WATER.length - 1; i < WATER.length; j = i++) {
    const [xi, yi] = WATER[i];
    const [xj, yj] = WATER[j];
    if ((yi > lon) !== (yj > lon) &&
        lat < ((xj - xi) * (lon - yi)) / (yj - yi) + xi) {
      inside = !inside;
    }
  }
  return inside;
}
Enter fullscreen mode Exit fullscreen mode

Carrier Tracking via GDELT

The Navy does not publish carrier positions. But GDELT ingests news worldwide and extracts locations. Querying for carrier names (CVN-68 through CVN-78) gives ~100km accuracy.

All Data Sources Are Free

Source Data Key Required
AISStream Vessel positions Free tier
EIA Oil spot prices Free
FRED Historical oil Free
IMF PortWatch Transit counts No
Open-Meteo Weather No
GDELT Carrier positions No
Google News Headlines No

Run It Yourself

git clone https://github.com/johnsmalls22-rgb/hormuz-tracker.git
cd hormuz-tracker
npm install
cp .env.example .env.local
npm run dev
Enter fullscreen mode Exit fullscreen mode

What I Learned

  1. Maritime data is surprisingly accessible
  2. GPS drift is worse than expected — water polygon filter is essential
  3. Dark ship detection is estimation, not tracking
  4. Mapbox GL is perfect for geospatial intelligence dashboards

If you are interested in geopolitical intelligence, check out The Board — 766K+ articles from 6,000+ sources with AI analysis.

Full Hormuz blockade analysis


Questions? GitHub Issues

Top comments (0)