Skip to content

marklearst/diabetic-utils

Repository files navigation

🩸 Diabetic Utils

The professional TypeScript toolkit for diabetes analytics and clinical-grade health data.

Diabetic Utils Logo

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, zero any types, and clinical-grade glucose variability analytics. Trusted by developers, clinicians, and researchers.


πŸ“Š Status & Quality

Status codecov CI TypeScript Coverage npm npm downloads License


πŸš€ What's New in v1.4.0

🎯 Enhanced Time-in-Range (TIR)

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

πŸ›‘οΈ Type Safety Excellence

  • Zero any types - Complete type safety throughout
  • Type Predicates - Better TypeScript narrowing
  • Literal Types - as const for autocomplete perfection
  • Named Return Types - ConversionResult interface

πŸ“š Self-Documenting Code

  • Named Constants: GMI_COEFFICIENTS with clinical references
  • Working Examples: Every function has @example tags
  • Test Helpers: Reusable test utilities for your own projects

βœ… 100% Test Coverage

  • 205 passing tests
  • Every line, branch, and function covered
  • Defensive code properly documented

πŸ“¦ Installation

npm install diabetic-utils
# or
pnpm add diabetic-utils
# or
yarn add diabetic-utils

Requirements: TypeScript 4.5+ or JavaScript (ES2020+)


⚑ Quick Start

Basic Conversions & Calculations

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

Enhanced Time-in-Range (NEW!)

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...']

Pregnancy TIR (NEW!)

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!...']

Glucose Labeling & Validation

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

Clinical Variability Analytics

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`)

Custom Thresholds

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'

🌟 Features

Core Utilities

  • βœ… 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)

Quality & DX

  • βœ… TypeScript-First: 100% strict mode, zero any types
  • βœ… 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

πŸ† Why Choose Diabetic Utils?

Clinical-Grade Accuracy

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

Production-Ready

  • 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.

Developer-Friendly

  • Clear API - Predictable function signatures
  • Great DX - Autocomplete with literal types
  • Working Examples - Copy-paste ready code
  • Test Helpers - Utilities for your own tests

Unique Features

Only TypeScript/JavaScript library with:

  • Enhanced TIR (5-range breakdown)
  • Pregnancy-specific TIR metrics
  • Clinical-grade MAGE calculation
  • Type predicates for validation

πŸ“š Full API Reference

Glucose Conversions

  • mgDlToMmolL(value) - Convert mg/dL to mmol/L
  • mmolLToMgDl(value) - Convert mmol/L to mg/dL
  • convertGlucoseUnit({ value, unit }) - Generic unit conversion

A1C & GMI

  • estimateA1CFromAverage(glucose, unit) - A1C from average glucose
  • estimateGMI(input, unit?) - GMI from average glucose
  • a1cToGMI(a1c) - Convert A1C to GMI
  • a1cToAverageGlucose(a1c, unit) - A1C to eAG

Time-in-Range

  • calculateTimeInRange(readings, low, high) - Basic TIR
  • calculateEnhancedTIR(readings, options?) - 5-range TIR
  • calculatePregnancyTIR(readings, options?) - Pregnancy TIR

Glucose Analysis

  • getGlucoseLabel(value, unit, thresholds?) - Label as low/normal/high
  • isHypo(value, unit, threshold?) - Check hypoglycemia
  • isHyper(value, unit, threshold?) - Check hyperglycemia
  • isValidGlucoseValue(value, unit) - Validate glucose value

A1C Analysis

  • getA1CCategory(a1c, cutoffs?) - Categorize A1C
  • isA1CInTarget(a1c, target?) - Check if A1C meets target

Variability Metrics

  • glucoseStandardDeviation(readings) - SD (unbiased)
  • glucoseCoefficientOfVariation(readings) - CV%
  • glucosePercentiles(readings, percentiles) - Percentile ranks
  • calculateMAGE(readings) - Mean Amplitude of Glycemic Excursions

Insulin Metrics

  • calculateHOMAIR(glucose, insulin, unit) - HOMA-IR
  • isValidInsulin(value) - Validate insulin value

Utilities

  • parseGlucoseString(str) - Parse "120 mg/dL" β†’ { value, unit }
  • formatGlucose(value, unit) - Format glucose with unit
  • isValidGlucoseString(str) - Validate glucose string

View Complete API Docs β†’


πŸ§ͺ Test Helpers (NEW!)

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

πŸ”¬ Clinical References

All calculations are based on peer-reviewed clinical sources:


πŸ—οΈ Architecture

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

🀝 Contributing

Contributions are welcome! Please follow these steps:

  1. Fork the repository
  2. Create your feature branch: git checkout -b feat/my-feature
  3. Add tests for any new functionality
  4. Ensure 100% coverage: pnpm test:coverage
  5. Commit with conventional commits: git commit -m "feat: add new feature"
  6. Push to your branch: git push origin feat/my-feature
  7. Open a pull request

Development Commands

# 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

πŸ“ Changelog

See CHANGELOG.md for detailed release notes and version history.


πŸ“„ License

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.


πŸ”— Links


πŸ™‹β€β™‚οΈ Author

Mark Learst Full-stack developer, diabetes advocate, and open source contributor.

πŸ’¬ 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!


πŸ’¬ Support


πŸ“ A Personal Note

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.

About

🩸 A modern TypeScript utility library for glucose, A1C, and diabetic health data.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published