Peta risiko stunting interaktif mencakup 514 kabupaten/kota di seluruh Indonesia Data real-time dari SSGI, Riskesdas, BPS Susenas โ ditenagai ML pipeline & narasi LLM
StuntingMap is a production-grade geospatial intelligence platform tracking child stunting risk across all 514 Indonesian districts (kabupaten/kota). Built as a senior AI engineer portfolio project demonstrating:
- Real data: SSGI 2022, Riskesdas 2018, BPS Susenas 2023 โ no synthetic data
- ML models: XGBoost + SHAP for stunting prediction, PySAL for spatial autocorrelation
- LLM narratives: Pre-generated GPT-4o-mini district reports in Bahasa Indonesia
- Geospatial: MapLibre GL JS choropleth with 8 data layers + time slider (2013-2024)
National context: Indonesia's stunting prevalence was 19.8% in 2024, missing the 14% national target. The worst-affected province is NTT at 35.9%; the best is Bali at 10.9%.
Indonesia recorded 19.8% stunting prevalence in 2024 โ missing the 14% national target by 5.8 percentage points.
| Province | Prevalence | Status |
|---|---|---|
| NTT | 35.9% | ๐ด Worst |
| Papua | 32.5% | ๐ด Critical |
| Sulawesi Barat | 31.5% | ๐ด Critical |
| Maluku | 29.2% | ๐ High |
| DKI Jakarta | 10.2% | ๐ข Best |
| Bali | 12.8% | ๐ข Below target |
| DIY Yogyakarta | 13.5% | ๐ข Below target |
| Feature | Description |
|---|---|
| ๐บ๏ธ Choropleth Map | MapLibre GL JS, 8 data layers, per-district interactive tooltips |
| โฑ๏ธ Time Slider | Temporal animation 2013โ2024, adjustable speed |
| ๐ National Dashboard | KPI cards, progress gauge toward 14% target, provincial ranking |
| ๐ District Comparison | Side-by-side comparison across kabupaten/kota |
| ๐ง ML Pipeline | XGBoost + SHAP, Moran's I, LISA spatial clustering |
| ๐ LLM Narratives | GPT-4o-mini, pre-generated in Bahasa Indonesia |
| ๐จ Colorblind-safe | YlOrRd (stunting/SRI) ยท RdYlGn (WASH/health) |
| ๐ฑ Responsive | Tablet-friendly, touch gestures supported |
| ๐ Auth | Full public access + researcher login for saved views |
| Layer | Technology |
|---|---|
| Frontend | Next.js 16 (App Router), TypeScript, Tailwind CSS |
| Map | MapLibre GL JS, GeoJSON (optimized <3MB) |
| Charts | Recharts, D3 (SVG gauges) |
| State | Zustand |
| Database | PostgreSQL + PostGIS (via Drizzle ORM) |
| Cache | Redis (ioredis) |
| ML Pipeline | Python: XGBoost, SHAP, PySAL, Pydantic v2 |
| LLM | OpenAI GPT-4o-mini (pre-generated, cached) |
| Orchestration | Prefect |
| Package Manager | pnpm workspaces + Turborepo |
| Deploy | Vercel (web) + Railway/Docker (ML service) |
| Dataset | Source | Coverage | License |
|---|---|---|---|
| SSGI 2022 (Survei Status Gizi Indonesia) | Kemenkes RI | 34 provinsi, 514 kab/kota | Public |
| Riskesdas 2018 | Badan Litbangkes | Nasional | Public |
| BPS Susenas 2023 | Badan Pusat Statistik | Nasional | Public |
| HDX Indonesia Admin Boundaries | OCHA/HDX | Level 2 (kab/kota) | CC BY |
| PODES 2021 | BPS | 83,794 desa | Public |
Transparency note: Where district-level data is unavailable for specific years, this platform uses ML models (XGBoost) to estimate values. All modeled values are clearly labeled as "Estimasi Model" versus measured "Data Terukur" throughout the interface.
- Node.js โฅ 18, pnpm โฅ 9
- Docker Desktop (for PostgreSQL + Redis)
- Python 3.11+ (for ML pipeline)
- OpenAI API key (optional, for LLM narratives)
# Clone repository
git clone https://github.com/vaskoyudha/StuntingMap.git
cd StuntingMap
# Install dependencies
pnpm install
# Start infrastructure
docker compose up -d
# Copy environment variables
cp .env.example .env.local
# Edit .env.local with your credentials
# Setup database
pnpm db:push
pnpm db:seed
# Start development server
pnpm devThe app will be available at http://localhost:3000
DATABASE_URL=postgresql://stuntingmap:stuntingmap@localhost:5432/stuntingmap
REDIS_URL=redis://localhost:6379
OPENAI_API_KEY=sk-your-key-here # Optional โ template narratives used if missing
NEXT_PUBLIC_APP_URL=http://localhost:3000
ML_API_URL=http://localhost:8000
NEXTAUTH_SECRET=your-secret-here
PIPELINE_SECRET=your-pipeline-secretStuntingMap/
โโโ apps/
โ โโโ web/ # Next.js 16 App Router
โ โ โโโ app/ # Pages + API routes
โ โ โ โโโ map/ # Interactive map page
โ โ โ โโโ dashboard/ # National analytics
โ โ โ โโโ compare/ # District comparison
โ โ โ โโโ api/ # REST API (15 routes)
โ โ โโโ components/
โ โ โ โโโ map/ # MapLibre components (6)
โ โ โ โโโ district/ # District panel (8)
โ โ โ โโโ dashboard/ # Dashboard widgets (5)
โ โ โ โโโ shared/ # Reusable UI (4)
โ โ โโโ lib/ # DB, Redis, colors, utils
โ โ โโโ store/ # Zustand state management
โ โโโ pipeline/ # Python ML service
โ โโโ analysis/ # Moran's I, LISA
โ โโโ models/ # XGBoost, SRI, trajectory
โ โโโ narratives/ # LLM generation
โ โโโ pipelines/ # Prefect orchestration
โโโ packages/
โ โโโ db/ # Drizzle schema (9 tables)
โ โโโ shared/ # Shared TypeScript types
โโโ scripts/
โ โโโ ingest/ # Data ingestion (Python)
โ โโโ tiles/ # GeoJSON generation
โโโ data/processed/ # Real Indonesian CSV data
| Endpoint | Method | Description |
|---|---|---|
/api/geojson |
GET | GeoJSON boundaries + stunting data |
/api/layers |
GET | Available data layers |
/api/districts |
GET | All districts with latest data |
/api/districts/[pcode] |
GET | Single district detail |
/api/districts/[pcode]/report |
GET | Full district report |
/api/districts/[pcode]/peers |
GET | Peer comparison districts |
/api/national |
GET | National-level statistics |
/api/scatter |
GET | Scatter plot correlation data |
/api/v1/districts |
GET | Public API v1 |
SRI is a composite index (0โ1) combining:
- Prevalence score (30%): Current stunting prevalence normalized nationally
- Trend score (20%): Historical trajectory (improving vs worsening)
- Determinant score (30%): WASH access, poverty, education composite
- Intervention gap score (20%): Healthcare coverage gaps
- Global Moran's I: Tests for spatial clustering of stunting across Indonesia
- LISA (Local Moran's I): Identifies HH/LL/HL/LH clusters at district level
- Weights: K-nearest neighbors (k=8), row-standardized, robust for archipelago geography
Three scenarios based on historical trend slope:
- BAU: Business as usual โ continues historical trend
- Accelerated: 2.5ร BAU decline with intensive intervention
- Minimal: 0.3ร BAU decline with reduced resources
# TypeScript type checking
cd apps/web && pnpm tsc --noEmit
# Python ML pipeline tests (9/9 passing)
cd apps/pipeline && pytest tests/ -vvercel deploydocker build -t stunting-pipeline apps/pipeline/
railway up- Fork the repository
- Create your feature branch (
git checkout -b feat/amazing-feature) - Commit your changes (
git commit -m 'feat: add amazing feature') - Push to the branch (
git push origin feat/amazing-feature) - Open a Pull Request
MIT License โ see LICENSE for details.
Data from SSGI, Riskesdas, and BPS Susenas is used under Indonesian government open data provisions. HDX boundaries under CC BY OCHA.
If you use StuntingMap data or methodology in research, please cite:
@software{stuntingmap2024,
title = {StuntingMap: Platform Intelijen Geospasial Stunting Indonesia},
author = {Nodyatama, Vasco Yudha},
year = {2024},
url = {https://github.com/vaskoyudha/StuntingMap},
note = {Data: SSGI 2022 (Kemenkes RI), Riskesdas 2018, BPS Susenas 2023}
}Dibuat untuk mendukung penurunan stunting di Indonesia ๐ฎ๐ฉ
๐บ๏ธ Map ยท ๐ Dashboard ยท ๐ Report Bug ยท ๐ก Request Feature

