A SQL-like query language for Apple HealthKit. Query your health data using familiar SQL syntax or a type-safe Swift DSL.
SELECT avg(value), min(value), max(value) FROM heart_rate WHERE date > today() - 7d GROUP BY day
Features
- SQL-like Syntax - Query HealthKit with familiar SELECT, FROM, WHERE, GROUP BY, ORDER BY, LIMIT
- Type-safe Swift DSL - Fluent API for building queries programmatically
- React Native / Expo Support - Use HealthQL in React Native apps with full TypeScript types
- 33 Quantity Types - Heart rate, steps, calories, VO2 max, swimming, and more
- 5 Category Types - Sleep analysis, headache, fatigue, appetite, menstrual flow
- Workouts & Sleep Sessions - Query exercise data and aggregated sleep metrics
- Date Functions -
today(),start_of_week(),start_of_month(),start_of_year() - Aggregations - SUM, AVG, MIN, MAX, COUNT with GROUP BY support
- Full Predicate Support - All comparison operators, AND, IS NULL, IS NOT NULL
Expanding Coverage: We're working toward full HealthKit SDK support. See our Roadmap for nutrition, symptoms, and 70+ additional workout types coming soon.
Installation
React Native / Expo
npm install react-native-healthql
Add the config plugin to your app.json:
{
"expo": {
"plugins": [
[
"react-native-healthql",
{
"healthShareUsageDescription": "Read health data to display insights"
}
]
]
}
}Then rebuild your app:
npx expo prebuild --clean npx expo run:ios
Swift Package Manager
Add HealthQL to your Package.swift:
dependencies: [ .package(url: "https://github.com/glisom/HealthQL.git", from: "1.0.0") ]
Then add the products you need:
.target( name: "YourApp", dependencies: [ "HealthQL", // Core types and execution "HealthQLParser", // SQL string parsing ] )
CocoaPods
pod 'HealthQL', '~> 1.1.0'
Quick Start
React Native / TypeScript
import { HealthQL } from 'react-native-healthql'; // Request authorization first await HealthQL.requestAuthorization({ read: ['heart_rate', 'steps', 'sleep_analysis'], }); // Execute a SQL query const results = await HealthQL.query(` SELECT avg(value) FROM heart_rate WHERE date > today() - 7d GROUP BY day `); results.forEach(row => { console.log(`${row.date}: ${row.avg_value} bpm`); });
Swift - SQL String Queries
import HealthQL import HealthQLParser // Parse and execute a query let result = try await HQL.query(""" SELECT sum(value) FROM steps WHERE date > today() - 7d GROUP BY day """) for row in result.rows { print("\(row["date"]!): \(row["sum_value"]!) steps") }
Swift DSL
import HealthQL let result = try await Health.select(.steps, aggregate: .sum) .where(.date, .greaterThan, .date(.daysAgo(7))) .groupBy(.day) .execute()
Supported Health Types
Quantity Types
33 quantity types including:
| Type | SQL Name | Unit |
|---|---|---|
| Heart Rate | heart_rate |
bpm |
| Resting Heart Rate | resting_heart_rate |
bpm |
| Steps | steps |
count |
| Active Calories | active_calories |
kcal |
| Distance | distance |
m |
| VO2 Max | vo2_max |
mL/(kg·min) |
| Body Mass | body_mass |
kg |
| Body Mass Index | body_mass_index |
- |
| Blood Oxygen | oxygen_saturation |
% |
| Blood Pressure | blood_pressure_systolic |
mmHg |
| Blood Glucose | blood_glucose |
mg/dL |
Category Types
| Type | SQL Name |
|---|---|
| Sleep Analysis | sleep_analysis |
| Appetite Changes | appetite_changes |
| Headache | headache |
| Fatigue | fatigue |
| Menstrual Flow | menstrual_flow |
Special Types
| Type | SQL Name | Description |
|---|---|---|
| Workouts | workouts |
Exercise sessions with duration, calories, type |
| Sleep Sessions | sleep |
Aggregated nightly sleep with stage breakdown |
Query Examples
Basic Queries
-- All heart rate readings from today SELECT * FROM heart_rate WHERE date > today() -- Latest 10 weight measurements SELECT value, date FROM body_mass ORDER BY date DESC LIMIT 10 -- Steps with source device info SELECT value, date, source, device FROM steps WHERE date > today() - 7d
Aggregations
-- Daily step totals for the past month SELECT sum(value) FROM steps WHERE date > today() - 30d GROUP BY day -- Weekly average heart rate SELECT avg(value), min(value), max(value) FROM heart_rate WHERE date > start_of_month() GROUP BY week -- Monthly calorie burn SELECT sum(value) FROM active_calories WHERE date > start_of_year() GROUP BY month
Workouts
-- Recent workouts with details SELECT duration, total_calories, activity_type FROM workouts ORDER BY date DESC LIMIT 20 -- Weekly workout summary SELECT sum(duration), sum(total_calories) FROM workouts WHERE date > today() - 30d GROUP BY week
Sleep
-- Sleep sessions for the past week SELECT * FROM sleep WHERE date > today() - 7d ORDER BY date DESC -- Raw sleep analysis data SELECT * FROM sleep_analysis WHERE date > today() - 7d
Filtering
-- High heart rate readings SELECT * FROM heart_rate WHERE value > 100 -- Heart rate in normal range SELECT * FROM heart_rate WHERE value > 60 AND value < 100 -- Readings with device info SELECT * FROM heart_rate WHERE device IS NOT NULL
Date Functions
| Function | Description |
|---|---|
today() |
Start of current day |
start_of_week() |
Start of current week |
start_of_month() |
Start of current month |
start_of_year() |
Start of current year |
Duration Syntax
| Unit | Syntax | Example |
|---|---|---|
| Days | d |
7d |
| Weeks | w |
4w |
| Months | mo |
3mo |
| Years | y |
1y |
-- Last 7 days WHERE date > today() - 7d -- Last 4 weeks WHERE date > today() - 4w -- Last 3 months WHERE date > today() - 3mo
Architecture
HealthQL uses a multi-stage architecture:
SQL String → Lexer → Parser → AST → Compiler → HealthQuery IR → Executor → Results
↑
Swift DSL → QueryBuilder ──────────────────────────────┘
Modules
| Module | Purpose |
|---|---|
HealthQL |
Core types, IR, DSL, HealthKit execution |
HealthQLParser |
SQL lexer, parser, compiler |
HealthQLPlayground |
REPL engine, formatting, autocomplete |
Requirements
- iOS 15.0+ / macOS 13.0+
- Swift 6.0+
- HealthKit entitlement
HealthKit Setup
- Add HealthKit capability to your app
- Add usage descriptions to Info.plist:
<key>NSHealthShareUsageDescription</key> <string>Read health data to display query results</string>
- Request authorization (HealthQL requests automatically on first query, or manually):
let store = HKHealthStore() try await store.requestAuthorization(toShare: [], read: [ HKQuantityType(.heartRate), HKQuantityType(.stepCount), // ... other types ])
Example App
The HealthQLApp directory contains a sample iOS app demonstrating:
- Query input with syntax highlighting
- Demo query buttons for common queries
- Result display with formatting
- HealthKit authorization flow
License
MIT License - see LICENSE file for details.
Contributing
Contributions welcome! Please read the contributing guidelines before submitting PRs.
Built with Swift and HealthKit.