Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

me-indicator-toolkit

A dependency-light, standards-based Monitoring & Evaluation toolkit for public health, development, and campaign programmes.

No server. No DHIS2 instance required. No framework lock-in. Just correct, tested formulas for the calculations every M&E team does by hand in Excel — coverage math, RDQA scoring, data quality checks, logframe tracking, campaign-day performance tiering, and DHIS2 interoperability — as a single JavaScript library you can drop into a spreadsheet tool, a Firebase app, a CLI, or a Node backend.

Why this exists

Most open-source M&E tooling falls into one of two camps: fully DHIS2-locked (powerful, but requires a running instance and admin access most district-level and NGO teams don't have), or ad-hoc Excel macros that live on one person's laptop and die when they leave. This toolkit is neither — it's the calculation layer, extracted and made portable, so you can build whatever interface you need on top of it.

Built out of real field use: day-by-day tiering logic from live polio SIA rounds, RDQA scoring from routine facility data quality assessments, and logframe tracking from an active Ebola virus disease M&E plan — generalized into reusable, tested functions.

Install

npm install me-indicator-toolkit

Or clone directly:

git clone https://github.com/<your-username>/me-indicator-toolkit.git
cd me-indicator-toolkit
npm install
npm test

Modules

Module What it does
coverage Administrative & survey coverage, dropout rate, target population estimation, coverage gap, facility-level rollups with tiering
rdqa Routine Data Quality Assessment — Verification Factor scoring, batch verification, system dimension (availability/completeness/timeliness/accuracy) scoring
dataQuality Report completeness, timeliness, missing facility detection, z-score outlier detection, period-over-period change flags
tiering Day-by-day SIA/campaign performance tiering, pro-rated daily targets, redeployment candidate identification, end-of-campaign projection
Logframe / Indicator Baseline/target/actual tracking with automatic percent-achievement and status classification, for any results framework
dhis2 Convert to/from DHIS2 dataValueSet import/export format, period string builders, payload validation
statistics Sample size calculation (Cochran's formula, with finite population correction and design effect), sample size for comparing two proportions, Wilson score confidence intervals, two-proportion z-test, LQAS decision rule
sampling PPS (probability proportional to size) cluster allocation, proportional and equal stratified allocation, systematic sampling interval calculation
economics Cost per output, cost per beneficiary, incremental cost-effectiveness ratio (ICER), budget utilization rate, cost per coverage point gained
TheoryOfChange / ResultsChainNode / contributionScore Build and validate a results chain (input→activity→output→outcome→impact), catch orphaned outcomes and backward links, score plausibility of programme contribution using contribution-analysis logic
qualitative Thematic code frequency tallying, code co-occurrence detection, thematic saturation tracking for mixed-methods M&E
indicators.immunization FIC rate, DTP1→DTP3 dropout, vaccine wastage, cold chain functionality
indicators.hiv ART coverage, viral load suppression/coverage, UNAIDS 95-95-95 cascade, retention rate, MTCT rate
indicators.tb Treatment success rate, case notification rate, TB/HIV testing rate, loss to follow-up rate
indicators.maternalHealth ANC4+ coverage, skilled birth attendance, institutional delivery rate, maternal mortality ratio, PNC coverage
indicators.nutrition GAM prevalence with severity classification, stunting prevalence, SPHERE-standard recovery/default rates, exclusive breastfeeding rate
indicators.malaria Test positivity rate, ITN ownership/use rate, incidence rate, case fatality rate, IRS coverage
indicators.wash JMP service ladder classification, basic water/sanitation access, open defecation rate, handwashing facility coverage, water point functionality
indicators.familyPlanning mCPR, unmet need, demand satisfied, couple-years of protection (CYP) with standard FP2030 conversion factors

Quick start

const met = require('me-indicator-toolkit');

// Coverage
met.coverage.administrativeCoverage(950, 1000); // 95

// Campaign day tiering (from a live 7-day SIA)
met.tiering.tierDayBatch(
  [
    { facility: 'Molepolole Clinic', cumulativeDoses: 450, targetPopulation: 1000 },
    { facility: 'Lentsweletau Clinic', cumulativeDoses: 60, targetPopulation: 1000 }
  ],
  3, // day 3
  7  // of a 7-day campaign
);
// => redeploymentCandidates: ['Lentsweletau Clinic']

// Logframe tracking
const { Logframe } = met;
const lf = new Logframe('EVD Response M&E Plan 2026');
const ind = lf.addIndicator({ name: 'RDQA completion rate', baseline: 0, target: 100 });
ind.logActual('2026-Q2', 65);
ind.status(); // 'at_risk'

// RDQA verification factor
met.rdqa.verificationFactor(98, 100); // { vf: 98, classification: 'match' }

// UNAIDS 95-95-95 cascade
met.indicators.hiv.cascade9595(1000, 950, 900, 855);

// Push clean data into DHIS2
met.dhis2.toDataValueSet({
  dataSet: 'abc123',
  orgUnit: 'ou456',
  period: met.dhis2.toDhis2Period(new Date(), 'Monthly'),
  values: [{ dataElement: 'de1', value: 42 }]
});

// Sample size for a coverage survey (95% CI, ±5% margin, design effect 2 for cluster sampling)
met.statistics.sampleSizeForProportion(0.5, 0.05, 95, null, 2);

// Is the difference between baseline and endline coverage statistically significant?
met.statistics.twoProportionZTest(320, 500, 410, 500); // baseline vs endline successes/n

// Allocate survey clusters proportional to population (PPS)
met.sampling.ppsClusterAllocation(
  [{ area: 'Molepolole', population: 70000 }, { area: 'Thamaga', population: 15000 }],
  20
);

// Cost-effectiveness comparison between two delivery approaches
met.economics.incrementalCostEffectivenessRatio(10000, 10, 15000, 20);

// Build and validate a Theory of Change
const toc = new met.TheoryOfChange('EVD Response ToC');
toc.addNode({ id: 'act1', level: 'activity', description: 'Train 40 CHWs', linksTo: ['out1'] });
toc.addNode({ id: 'out1', level: 'output', description: 'CHWs trained', linksTo: ['outcome1'] });
toc.addNode({ id: 'outcome1', level: 'outcome', description: 'Faster alert response' });
toc.validate(); // flags orphaned outcomes, backward links, missing targets

// Score plausibility of programme contribution to an observed outcome
met.contributionScore({
  resultsChainPlausible: true,
  activitiesImplemented: true,
  otherFactorsAssessed: true,
  outcomeObserved: true
});

// Thematic saturation from a sequence of interviews
met.qualitative.saturationTracker([
  { interview: 'I1', newCodesIntroduced: 5 },
  { interview: 'I2', newCodesIntroduced: 0 },
  { interview: 'I3', newCodesIntroduced: 0 },
  { interview: 'I4', newCodesIntroduced: 0 }
], 3);

See examples/ for fuller worked examples, including a full SIA campaign-day workflow and an EVD logframe setup.

CLI

For non-developers, the most common reports are available as command-line commands against a CSV file — no JavaScript required.

npm install -g me-indicator-toolkit
# or, from a cloned repo: node bin/cli.js <command> ...

me-toolkit coverage-rollup facilities.csv --target=90
# Expected columns: facility,dosesAdministered,targetPopulation

me-toolkit rdqa-batch rdqa-data.csv
# Expected columns: indicator,sourceCount,reportedCount

me-toolkit completeness reporting.csv
# Expected columns: facility,reported (1/0 or true/false)

me-toolkit sample-size --p=0.5 --margin=0.05 --confidence=95 --deff=2

me-toolkit --help

Sample CSVs to try these against are in examples/sample-data/.

Design principles

  • Pure functions. No I/O, no global state, no side effects. Every function takes plain data in and returns plain data out — easy to test, easy to embed anywhere.
  • Cited formulas. Every indicator formula follows a named, documented standard (WHO EPI, PEPFAR MER 2.0, UNAIDS 95-95-95, SPHERE, WHO RDQA methodology) — not an invented approximation.
  • Fails loud, not silent. Bad input (negative numbers, missing fields, out-of-range values) throws immediately rather than returning NaN or undefined that quietly corrupts a downstream report.
  • Zero runtime dependencies. The only dependency in this repo is jest, and only for testing.
  • DHIS2-adjacent, not DHIS2-dependent. You can use every module without ever touching a DHIS2 instance. The dhis2 module is there for teams that need to push data upstream once it's clean.

Testing

npm test              # run the full suite
npm run test:coverage # run with coverage report

170 tests across 13 suites.

Contributing

Indicator formulas are the highest-value contribution area — if your programme area (malaria, WASH, education, food security, etc.) isn't covered yet, open an issue with the standard formula and its source (WHO/UNAIDS/Global Fund/SPHERE/etc.) and a PR is very welcome. Keep new functions pure and add tests alongside them.

What this deliberately doesn't do

  • No NLP or auto-coding. qualitative.js aggregates codes a human analyst has already applied — it doesn't do sentiment analysis or automatic theme extraction. That's a defensible line, not a gap: automated qualitative coding without human judgment is a credibility risk in this field.
  • No discounting or DALY/QALY modeling in economics.js. Full health economic evaluation is its own discipline; this module covers what an M&E officer is routinely asked for, not what a health economist would build.
  • No live DHIS2 round-trip test out of the box — the dhis2 module's payload shape follows the documented API format, but ships untested against a running instance. Run scripts/verify-dhis2.js yourself against your own instance (or the public DHIS2 demo) to confirm before relying on it in production. Credentials are read from environment variables only — see the script's header for exact usage. Never commit or paste credentials anywhere; the script defaults to a read-only dry-run.
  • No visualization layer. Pure calculation — pair it with your own charting/dashboard layer.

License

MIT — see LICENSE.

Origin

Built by Kabo "Rogue" Onamile, a Public Health M&E professional working within Botswana's district health system, out of tooling originally developed for live nOPV2 polio SIA rounds and Ebola virus disease M&E planning at Kweneng District Health Management Team.

About

No description, website, or topics provided.

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages