@robinhealth/health-sdk 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Robin Health
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,189 @@
1
+ # @robin/health-sdk
2
+
3
+ Unified health data SDK for React Native — HealthKit (iOS) and Health Connect (Android).
4
+
5
+ One API, both platforms. Query steps, heart rate, sleep, workouts, body composition, and more without writing platform-specific code.
6
+
7
+ ## Features
8
+
9
+ - **19 health data types** — activity, vitals, sleep, body composition, hydration
10
+ - **79 workout types** — from running and cycling to pickleball and underwater diving
11
+ - **Sleep sessions** — full stage breakdowns (awake, light, deep, REM)
12
+ - **Aggregations** — sum, average, min, max over any date range
13
+ - **Permission management** — persistent state tracking via expo-sqlite
14
+ - **Type-safe** — full TypeScript definitions
15
+
16
+ ## Install
17
+
18
+ ```bash
19
+ npm install @robin/health-sdk
20
+ ```
21
+
22
+ Then install the platform-specific peer dependencies you need:
23
+
24
+ ```bash
25
+ # iOS
26
+ npm install @kingstinct/react-native-healthkit
27
+
28
+ # Android
29
+ npm install react-native-health-connect
30
+
31
+ # Permission persistence (recommended)
32
+ npm install expo-sqlite
33
+ ```
34
+
35
+ ## Platform Setup
36
+
37
+ ### iOS (Expo)
38
+
39
+ Add the HealthKit plugin to your `app.json`:
40
+
41
+ ```json
42
+ {
43
+ "expo": {
44
+ "plugins": [
45
+ [
46
+ "@kingstinct/react-native-healthkit",
47
+ {
48
+ "NSHealthShareUsageDescription": "This app needs access to your health data."
49
+ }
50
+ ]
51
+ ]
52
+ }
53
+ }
54
+ ```
55
+
56
+ ### iOS (Bare React Native)
57
+
58
+ 1. Enable the **HealthKit** capability in Xcode
59
+ 2. Add `NSHealthShareUsageDescription` to `Info.plist`
60
+ 3. Run `pod install`
61
+
62
+ ### Android (Expo)
63
+
64
+ Add the Health Connect plugin to your `app.json`:
65
+
66
+ ```json
67
+ {
68
+ "expo": {
69
+ "plugins": [
70
+ [
71
+ "expo-health-connect",
72
+ {
73
+ "permissions": [
74
+ "android.permission.health.READ_STEPS",
75
+ "android.permission.health.READ_HEART_RATE"
76
+ ]
77
+ }
78
+ ]
79
+ ]
80
+ }
81
+ }
82
+ ```
83
+
84
+ Requires `minSdkVersion` 28+.
85
+
86
+ ### Android (Bare React Native)
87
+
88
+ 1. Set `minSdkVersion` 28+ in `build.gradle`
89
+ 2. Declare health permissions in `AndroidManifest.xml`
90
+ 3. Add the `ViewPermissionUsageActivity` alias for the permissions rationale screen
91
+
92
+ See [docs/INTEGRATION.md](docs/INTEGRATION.md) for full setup instructions.
93
+
94
+ ## Quick Start
95
+
96
+ ```typescript
97
+ import {
98
+ createHealthProvider,
99
+ HealthDataType,
100
+ } from 'robin-health-sdk';
101
+
102
+ const provider = createHealthProvider();
103
+
104
+ // Check availability
105
+ const available = await provider.isAvailable();
106
+
107
+ // Request permissions
108
+ await provider.requestAuthorization([
109
+ HealthDataType.Steps,
110
+ HealthDataType.HeartRate,
111
+ HealthDataType.SleepAnalysis,
112
+ ]);
113
+
114
+ // Query samples
115
+ const now = new Date();
116
+ const yesterday = new Date(now.getTime() - 24 * 60 * 60 * 1000);
117
+
118
+ const heartRateSamples = await provider.querySamples(
119
+ HealthDataType.HeartRate,
120
+ yesterday,
121
+ now,
122
+ );
123
+
124
+ // Get aggregated stats
125
+ const stepTotal = await provider.queryAggregated(
126
+ HealthDataType.Steps,
127
+ yesterday,
128
+ now,
129
+ );
130
+ console.log(`Steps: ${stepTotal.sum}`);
131
+
132
+ // Query workouts
133
+ const workouts = await provider.queryWorkouts(yesterday, now);
134
+
135
+ // Query sleep sessions with stage breakdowns
136
+ const sleep = await provider.querySleepSessions(yesterday, now);
137
+ ```
138
+
139
+ ## Supported Data Types
140
+
141
+ | Category | Type | Unit |
142
+ |----------|------|------|
143
+ | **Activity** | Steps | count |
144
+ | | DistanceWalkingRunning | meters |
145
+ | | ActiveEnergyBurned | kcal |
146
+ | | FlightsClimbed | count |
147
+ | **Vitals** | HeartRate | bpm |
148
+ | | RestingHeartRate | bpm |
149
+ | | BloodPressureSystolic | mmHg |
150
+ | | BloodPressureDiastolic | mmHg |
151
+ | | BloodOxygen | % |
152
+ | | RespiratoryRate | breaths/min |
153
+ | **Sleep** | SleepAnalysis | hours |
154
+ | **Body** | BodyFatPercentage | % |
155
+ | | BodyMassIndex | kg/m² |
156
+ | | BasalEnergyBurned | kcal |
157
+ | **Hydration** | Water | mL |
158
+
159
+ ## API
160
+
161
+ ### `createHealthProvider(): HealthProvider`
162
+
163
+ Returns a platform-specific health provider (HealthKit on iOS, Health Connect on Android).
164
+
165
+ ### `HealthProvider`
166
+
167
+ | Method | Description |
168
+ |--------|-------------|
169
+ | `isAvailable()` | Check if health data is available on this device |
170
+ | `shouldRequestAuthorization(types)` | Check if permissions need to be requested |
171
+ | `requestAuthorization(types)` | Request read access for the given data types |
172
+ | `getPermissionStatus()` | Get current permission status |
173
+ | `querySamples(type, start, end)` | Get individual readings in a date range |
174
+ | `queryAggregated(type, start, end)` | Get aggregated stats (sum, avg, min, max) |
175
+ | `queryWorkouts(start, end)` | Get workout sessions with metadata |
176
+ | `querySleepSessions(start, end)` | Get sleep sessions with stage breakdowns |
177
+
178
+ See [docs/API.md](docs/API.md) for the full API reference with type definitions and platform notes.
179
+
180
+ ## Requirements
181
+
182
+ - Node >= 16
183
+ - React >= 18.0.0
184
+ - React Native >= 0.72.0
185
+ - iOS 13+ / Android SDK 28+
186
+
187
+ ## License
188
+
189
+ MIT — see [LICENSE](LICENSE) for details.
@@ -0,0 +1,4 @@
1
+ export { createHealthProvider } from './provider';
2
+ export type { HealthProvider, HealthSample, HealthAggregate, Workout, SleepStageSample, SleepSession, } from './types';
3
+ export { HealthDataType, WorkoutActivityType, PermissionStatus, SleepStage, } from './types';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,YAAY,EACV,cAAc,EACd,YAAY,EACZ,eAAe,EACf,OAAO,EACP,gBAAgB,EAChB,YAAY,GACb,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAChB,UAAU,GACX,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { createHealthProvider } from './provider';
2
+ export { HealthDataType, WorkoutActivityType, PermissionStatus, SleepStage, } from './types';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AASlD,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAChB,UAAU,GACX,MAAM,SAAS,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { HealthProvider } from './types';
2
+ export declare function createHealthProvider(): HealthProvider;
3
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,wBAAgB,oBAAoB,IAAI,cAAc,CAcrD"}
@@ -0,0 +1,13 @@
1
+ import { Platform } from 'react-native';
2
+ export function createHealthProvider() {
3
+ if (Platform.OS === 'ios') {
4
+ const { HealthKitProvider } = require('./providers/healthkit');
5
+ return new HealthKitProvider();
6
+ }
7
+ if (Platform.OS === 'android') {
8
+ const { HealthConnectProvider } = require('./providers/healthconnect');
9
+ return new HealthConnectProvider();
10
+ }
11
+ throw new Error(`Health data is not supported on ${Platform.OS}. Supported platforms: ios, android.`);
12
+ }
13
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAGxC,MAAM,UAAU,oBAAoB;IAClC,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,EAAE,CAAC;QAC1B,MAAM,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;QAC/D,OAAO,IAAI,iBAAiB,EAAE,CAAC;IACjC,CAAC;IAED,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;QAC9B,MAAM,EAAE,qBAAqB,EAAE,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAAC;QACvE,OAAO,IAAI,qBAAqB,EAAE,CAAC;IACrC,CAAC;IAED,MAAM,IAAI,KAAK,CACb,mCAAmC,QAAQ,CAAC,EAAE,sCAAsC,CACrF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { HealthDataType, PermissionStatus, type HealthProvider, type HealthSample, type HealthAggregate, type Workout, type SleepSession } from '../types';
2
+ export declare class HealthConnectProvider implements HealthProvider {
3
+ private initPromise;
4
+ private ensureInitialized;
5
+ isAvailable(): Promise<boolean>;
6
+ shouldRequestAuthorization(dataTypes: HealthDataType[]): Promise<boolean>;
7
+ requestAuthorization(dataTypes: HealthDataType[]): Promise<boolean>;
8
+ getPermissionStatus(): Promise<PermissionStatus>;
9
+ querySamples(type: HealthDataType, startDate: Date, endDate: Date): Promise<HealthSample[]>;
10
+ queryAggregated(type: HealthDataType, startDate: Date, endDate: Date): Promise<HealthAggregate>;
11
+ querySleepSessions(startDate: Date, endDate: Date): Promise<SleepSession[]>;
12
+ queryWorkouts(startDate: Date, endDate: Date): Promise<Workout[]>;
13
+ private deriveBMISamples;
14
+ private manualAggregate;
15
+ }
16
+ //# sourceMappingURL=healthconnect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"healthconnect.d.ts","sourceRoot":"","sources":["../../src/providers/healthconnect.ts"],"names":[],"mappings":"AAmBA,OAAO,EACL,cAAc,EAEd,gBAAgB,EAEhB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,OAAO,EAEZ,KAAK,YAAY,EAClB,MAAM,UAAU,CAAC;AAqJlB,qBAAa,qBAAsB,YAAW,cAAc;IAC1D,OAAO,CAAC,WAAW,CAAiC;YAEtC,iBAAiB;IAUzB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAU/B,0BAA0B,CAAC,SAAS,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAmCzE,oBAAoB,CAAC,SAAS,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAoCnE,mBAAmB,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAahD,YAAY,CAChB,IAAI,EAAE,cAAc,EACpB,SAAS,EAAE,IAAI,EACf,OAAO,EAAE,IAAI,GACZ,OAAO,CAAC,YAAY,EAAE,CAAC;IA2KpB,eAAe,CACnB,IAAI,EAAE,cAAc,EACpB,SAAS,EAAE,IAAI,EACf,OAAO,EAAE,IAAI,GACZ,OAAO,CAAC,eAAe,CAAC;IAwDrB,kBAAkB,CACtB,SAAS,EAAE,IAAI,EACf,OAAO,EAAE,IAAI,GACZ,OAAO,CAAC,YAAY,EAAE,CAAC;IAkEpB,aAAa,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;YAkEzD,gBAAgB;YA0ChB,eAAe;CA0B9B"}