Built and maintained by Mark Learst.
The professional TypeScript toolkit for diabetes analytics and clinical-grade health data.
A modern, strictly-typed utility library for glucose, A1C, insulin, and diabetes metrics. Designed for reliability, transparency, and real-world clinical useβno bloat, no guesswork, just robust utilities backed by authoritative clinical references.
β οΈ v1.4+ features enhanced TIR calculations, 100% test coverage, zeroanytypes, and clinical-grade glucose variability analytics. Trusted by developers, clinicians, and researchers.
Status codecov CI TypeScript Coverage npm npm downloads License
Clinical-grade TIR calculations per International Consensus 2019 and ADA 2024 Guidelines:
- 5-Range Enhanced TIR: Very Low, Low, In Range, High, Very High
- Pregnancy TIR: Tighter targets (63-140 mg/dL / 3.5-7.8 mmol/L)
- Clinical Recommendations: Automated insights based on targets
- Population-Specific Goals: Standard, older-adults, high-risk
- Zero
anytypes - Complete type safety throughout - Type Predicates - Better TypeScript narrowing
- Literal Types -
as constfor autocomplete perfection - Named Return Types -
ConversionResultinterface
- Named Constants:
GMI_COEFFICIENTSwith clinical references - Working Examples: Every function has
@exampletags - Test Helpers: Reusable test utilities for your own projects
- 205 passing tests
- Every line, branch, and function covered
- Defensive code properly documented
npm install diabetic-utils # or pnpm add diabetic-utils # or yarn add diabetic-utils
Requirements: TypeScript 4.5+ or JavaScript (ES2020+)
import { mgDlToMmolL, mmolLToMgDl, estimateGMI, estimateA1CFromAverage } from 'diabetic-utils' // Glucose unit conversions mgDlToMmolL(180) // β 10.0 mmolLToMgDl(5.5) // β 99 // GMI calculation (multiple input formats) estimateGMI(100, 'mg/dL') // β 5.4 estimateGMI('5.5 mmol/L') // β 5.4 estimateGMI({ value: 100, unit: 'mg/dL' }) // β 5.4 // A1C estimation estimateA1CFromAverage(154, 'mg/dL') // β 7.0
import { calculateEnhancedTIR } from 'diabetic-utils' import type { GlucoseReading } from 'diabetic-utils' const readings: GlucoseReading[] = [ { value: 120, unit: 'mg/dL', timestamp: '2024-01-01T08:00:00Z' }, { value: 95, unit: 'mg/dL', timestamp: '2024-01-01T08:05:00Z' }, { value: 180, unit: 'mg/dL', timestamp: '2024-01-01T08:10:00Z' }, // ... more readings ] const result = calculateEnhancedTIR(readings) console.log(`TIR: ${result.inRange.percentage}%`) // TIR: 72.5% console.log(`Very Low: ${result.veryLow.percentage}%`) // Very Low: 0.5% console.log(`Assessment: ${result.meetsTargets.overallAssessment}`) // Assessment: good console.log(result.meetsTargets.recommendations) // ['Excellent glycemic control! All metrics meet clinical targets...']
import { calculatePregnancyTIR } from 'diabetic-utils' const result = calculatePregnancyTIR(readings) console.log(`TIR (63-140 mg/dL): ${result.inRange.percentage}%`) // TIR (63-140 mg/dL): 85.2% console.log(`Meets pregnancy targets: ${result.meetsPregnancyTargets}`) // Meets pregnancy targets: true console.log(result.recommendations) // ['Excellent glycemic control for pregnancy!...']
import { getGlucoseLabel, isHypo, isHyper, isValidGlucoseValue } from 'diabetic-utils' // Label glucose values getGlucoseLabel(60, 'mg/dL') // β 'low' getGlucoseLabel(5.5, 'mmol/L') // β 'normal' getGlucoseLabel(200, 'mg/dL') // β 'high' // Clinical checks isHypo(65, 'mg/dL') // β true isHyper(180, 'mg/dL') // β false // Validation isValidGlucoseValue(120, 'mg/dL') // β true isValidGlucoseValue(-10, 'mg/dL') // β false
import { glucoseStandardDeviation, glucoseCoefficientOfVariation, glucosePercentiles, calculateMAGE } from 'diabetic-utils' const data = [90, 100, 110, 120, 130, 140, 150, 160, 170, 180] // Standard deviation (unbiased sample SD, n-1) glucoseStandardDeviation(data) // β 30.28 // Coefficient of variation (CV%) glucoseCoefficientOfVariation(data) // β 22.43 // Percentiles (nearest-rank method) glucosePercentiles(data, [10, 50, 90]) // β { 10: 90, 50: 130, 90: 170 } // MAGE (Mean Amplitude of Glycemic Excursions) const mage = calculateMAGE(readings) console.log(`MAGE: ${mage.value} mg/dL`)
import { getGlucoseLabel, isHypo, getA1CCategory } from 'diabetic-utils' // Custom hypoglycemia threshold isHypo(75, 'mg/dL', { mgdl: 80 }) // β true // Custom hyperglycemia threshold isHyper(9.0, 'mmol/L', { mmoll: 8.5 }) // β true // Custom glucose label thresholds getGlucoseLabel(75, 'mg/dL', { hypo: { mgdl: 80 }, hyper: { mgdl: 160 } }) // β 'low' // Custom A1C category cutoffs getA1CCategory(6.5, { normalMax: 6.0, prediabetesMax: 7.0 }) // β 'prediabetes'
- β Glucose Conversions: mg/dL β mmol/L
- β A1C Calculations: GMI, eAG, A1C estimation
- β Time-in-Range: Enhanced TIR (5 ranges), Pregnancy TIR
- β HOMA-IR: Insulin resistance calculation
- β Variability Metrics: SD, CV, MAGE, percentiles
- β Validation: Input guards, string parsing
- β Labeling: Glucose status (low/normal/high)
- β
TypeScript-First: 100% strict mode, zero
anytypes - β 100% Test Coverage: 205 tests, all edge cases covered
- β Zero Dependencies: No bloat, tree-shakable
- β Clinical References: ADA, CDC, ISPAD, PubMed citations
- β TSDoc: Complete API documentation
- β ESM + CJS: Works everywhere
- β Type Predicates: Better type narrowing
- β Named Constants: Self-documenting formulas
Every formula, threshold, and calculation is sourced from authoritative clinical guidelines:
- International Consensus on Time in Range (2019) - TIR calculations
- ADA Standards of Care (2024) - Pregnancy targets, A1C guidelines
- ISPAD Guidelines (2018) - Glucose variability metrics
- NIH/NIDDK - HOMA-IR, eAG formulas
- 100% Test Coverage - Every line tested
- Type-Safe - Catch errors at compile time
- Zero Dependencies - Small bundle, no supply chain risk
- Modern ESM - Tree-shakable, works with Vite, Next.js, etc.
- Clear API - Predictable function signatures
- Great DX - Autocomplete with literal types
- Working Examples - Copy-paste ready code
- Test Helpers - Utilities for your own tests
Only TypeScript/JavaScript library with:
- Enhanced TIR (5-range breakdown)
- Pregnancy-specific TIR metrics
- Clinical-grade MAGE calculation
- Type predicates for validation
mgDlToMmolL(value)- Convert mg/dL to mmol/LmmolLToMgDl(value)- Convert mmol/L to mg/dLconvertGlucoseUnit({ value, unit })- Generic unit conversion
estimateA1CFromAverage(glucose, unit)- A1C from average glucoseestimateGMI(input, unit?)- GMI from average glucosea1cToGMI(a1c)- Convert A1C to GMIa1cToAverageGlucose(a1c, unit)- A1C to eAG
calculateTimeInRange(readings, low, high)- Basic TIRcalculateEnhancedTIR(readings, options?)- 5-range TIRcalculatePregnancyTIR(readings, options?)- Pregnancy TIR
getGlucoseLabel(value, unit, thresholds?)- Label as low/normal/highisHypo(value, unit, threshold?)- Check hypoglycemiaisHyper(value, unit, threshold?)- Check hyperglycemiaisValidGlucoseValue(value, unit)- Validate glucose value
getA1CCategory(a1c, cutoffs?)- Categorize A1CisA1CInTarget(a1c, target?)- Check if A1C meets target
glucoseStandardDeviation(readings)- SD (unbiased)glucoseCoefficientOfVariation(readings)- CV%glucosePercentiles(readings, percentiles)- Percentile rankscalculateMAGE(readings)- Mean Amplitude of Glycemic Excursions
calculateHOMAIR(glucose, insulin, unit)- HOMA-IRisValidInsulin(value)- Validate insulin value
parseGlucoseString(str)- Parse "120 mg/dL" β { value, unit }formatGlucose(value, unit)- Format glucose with unitisValidGlucoseString(str)- Validate glucose string
Use our test utilities in your own projects:
import { createGlucoseReadings, COMMON_TEST_VALUES, TEST_TIMESTAMP_BASE } from 'diabetic-utils/tests/test-helpers' // Create test data easily const readings = createGlucoseReadings([100, 110, 120], 'mg/dL', 5) // β 3 readings at 5-minute intervals // Use common test values const { NORMAL_GLUCOSE_MGDL, HYPO_GLUCOSE_MGDL } = COMMON_TEST_VALUES
All calculations are based on peer-reviewed clinical sources:
- Time-in-Range: International Consensus (2019)
- Pregnancy TIR: ADA Standards of Care (2024)
- A1C/eAG: Nathan et al. (2008)
- HOMA-IR: Matthews et al. (1985)
- MAGE: Service et al. (1970)
- Variability: ISPAD Guidelines (2018)
diabetic-utils/
βββ src/
β βββ index.ts # Main exports
β βββ constants.ts # Clinical thresholds & formulas
β βββ types.ts # TypeScript types
β βββ conversions.ts # Glucose unit conversions
β βββ a1c.ts # A1C & GMI calculations
β βββ tir.ts # Basic time-in-range
β βββ tir-enhanced.ts # Enhanced & pregnancy TIR
β βββ glucose.ts # Glucose utilities
β βββ alignment.ts # HOMA-IR
β βββ variability.ts # SD, CV, percentiles
β βββ mage.ts # MAGE calculation
β βββ formatters.ts # String formatting
β βββ guards.ts # Type guards
β βββ validators.ts # Input validation
βββ tests/
β βββ test-helpers.ts # Shared test utilities
β βββ *.test.ts # 100% coverage tests
βββ dist/ # Built output (ESM + CJS)
Key Principles:
- β Zero dependencies
- β Tree-shakable modules
- β Strict TypeScript
- β 100% test coverage
- β Clinical references in TSDoc
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create your feature branch:
git checkout -b feat/my-feature - Add tests for any new functionality
- Ensure 100% coverage:
pnpm test:coverage - Commit with conventional commits:
git commit -m "feat: add new feature" - Push to your branch:
git push origin feat/my-feature - Open a pull request
# Install dependencies pnpm install # Run tests pnpm test # Run tests with coverage pnpm test:coverage # Build library pnpm build # Lint code pnpm lint # Type check pnpm typecheck
See CHANGELOG.md for detailed release notes and version history.
This project is licensed under the MIT License. See the LICENSE file for details.
Β© 2024β2025 Mark Learst
Use it, fork it, build something that matters.
- π¦ NPM Package
- π API Documentation
- π GitHub Repository
- π Website (coming soon)
Mark Learst Full-stack developer, diabetes advocate, and open source contributor.
- π¦ X (Twitter): @marklearst
- πΌ LinkedIn: Mark Learst
- π Portfolio: marklearst.com
π¬ Using diabetic-utils in your project? Let me knowβI'd love to feature it! β Star the repo and help us build the best diabetes toolkit together!
- π Bug Reports: Open an issue
- π‘ Feature Requests: Start a discussion
- π§ Email: mark@marklearst.com
I built diabetic-utils because I believe in the power of data-driven diabetes management. As someone who's lived with diabetes, I know how hard it can be to make sense of the numbers.
That's why I've poured my heart into creating a library that's both clinically accurate and easy to use. Whether you're building an app, working on research, or just trying to understand your own data, I hope diabetic-utils can help.
Let's work together to make diabetes management better, one data point at a time. π©Έ
Built with β€οΈ by the diabetes community, for the diabetes community.