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.
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-utilsRequirements: 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.0import { 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') // β falseimport {
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_VALUESAll 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 typecheckSee 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.
