Native iOS app for controlling and monitoring your sleepypod — temperature control, sleep tracking, biometrics, and on-device analysis.
- Radial dial with 1°F granularity and drag-to-set
- Ambient glow that pulses and changes color based on heating/cooling intensity
- Side selector with link mode (control both sides together)
- User profile with default side preference
- Real-time heart rate, HRV, and breathing rate charts
- Interactive tap-to-inspect with zone annotations (resting/normal/elevated)
- On-device sleep stage classification (rule-based, Core ML ready)
- Sleep quality scoring based on stage distribution
- Raw data export to CSV
- Outlier filtering and data smoothing
- Temperature curve editor with per-phase +/- controls
- AI-generated sleep curves with "use now" shortcut
- Alarm and bedtime time pickers
- Power schedule toggle
- Day-of-week and side selection
- Profile presets (Cool, Balanced, Warm)
- Service health dashboard with expandable categories
- Real-time wifi signal, water level, calibration status
- Sensor calibration per side (capacitance, piezo, temperature)
- On-device ML model inventory
- Internet access toggle (iptables firewall control)
- System log viewer (journalctl)
- mDNS network discovery
- Automatic mDNS discovery (
_sleepypod._tcp) - Step-by-step connection progress UI
- Manual IP override fallback
- 10-second polling with pull-to-refresh
SleepypodProtocol <- shared interface for all backends
├── FreeSleepClient <- legacy free-sleep REST API
└── SleepypodCoreClient <- sleepypod-core tRPC API
DeviceManager <- temperature, power, polling
ScheduleManager <- schedules, alarms
StatusManager <- service health, server status
SettingsManager <- device config, timezone, temp format
MetricsManager <- sleep records, vitals, movement
PodDiscovery <- mDNS/Bonjour network discovery
SleepAnalyzer <- on-device sleep stage classification
UserProfile <- local user preferences
Any backend conforms to SleepypodProtocol and the entire app works — no view changes needed.
- iOS 26.0+
- Xcode 26+
- Swift 6.0
- A sleepypod on the local network
# Clone
git clone https://github.com/sleepypod/ios.git
cd ios
# Install dependencies
npm install
# Generate Xcode project (requires XcodeGen)
brew install xcodegen
xcodegen generate
# Open in Xcode
open Sleepypod.xcodeproj# Build for device
xcodebuild -scheme Sleepypod -destination 'platform=iOS,name=YOUR_DEVICE' \
DEVELOPMENT_TEAM=YOUR_TEAM_ID build
# Install via devicectl
xcrun devicectl device install app --device DEVICE_ID \
~/Library/Developer/Xcode/DerivedData/Sleepypod-*/Build/Products/Debug-iphoneos/Sleepypod.app# Check (same as CI)
npm run lint
# Auto-fix + check
npm run lint:fixRequires SwiftLint: brew install swiftlint
# Fetch the latest OpenAPI spec from a running pod
./scripts/sync-api-spec.sh 192.168.1.88Every PR runs contract tests that validate iOS model types against the live sleepypod-core API:
- Starts a sleepypod-core dev server
- Snapshots tRPC endpoint responses
- Decodes with Swift model types
- Fails if any model change breaks API compatibility
Also runs daily to catch core-side drift.
# Run locally
cd contract-tests && swift testAll checks run on every PR and must pass before merge:
| Job | Runner | What it does |
|---|---|---|
| build | macos-26 |
xcodebuild build — catches compile errors |
| lint | macos-15 |
SwiftLint — enforces code style |
| contract-test | macos-15 |
Validates models against live core API |
Sleepypod/
├── Models/ # Codable types (dual-format: free-sleep + core)
├── Networking/ # API clients, protocol, endpoints
├── Services/ # Managers, discovery, ML analyzer, logging
├── Views/
│ ├── Temp/ # Temperature dial, controls, side selector
│ ├── Schedule/ # Schedule editor, phase blocks, day selector
│ ├── Data/ # Health screen, charts, raw data export
│ ├── Status/ # Service health, calibration, logs, network
│ └── Settings/ # Device settings, tap gestures
├── openapi.json # Committed API spec
└── Info.plist # Bonjour service type
- Health Vitals Science — measurement principles, normal ranges, filtering, and references
- ADR-001 — Protocol abstraction for multi-backend support
- ADR-002 — mDNS/Bonjour for pod discovery
- ADR-003 — Contract testing between iOS and core
- ADR-004 — On-device sleep analysis with Core ML
- ADR-005 — Dual-format Decodable models
Need help? Join the Discord or open an issue.
- sleepypod/core — server for pod hardware control, scheduling, biometrics processing, and API
AGPL-3.0. The app is free; build it yourself from this source or install it from the App Store.
App Store exception. The copyright holder (Jonathan Ng) also distributes compiled builds of sleepypod through Apple's App Store and TestFlight under Apple's terms, which the Free Software Foundation considers incompatible with the AGPL. This is permitted because the copyright holder grants it; it does not change the licence of the source, and it does not extend to anyone else's App Store builds. Contributors agree to the same grant for their changes — see CONTRIBUTING.md.
The bundled IBM Plex Mono fonts are under the SIL Open Font License 1.1. There are no other third-party components.
sleepypod is an independent project, not affiliated with, endorsed by, or sponsored by Eight Sleep, Inc. Eight Sleep and Pod are trademarks of Eight Sleep, Inc., named only to identify compatible hardware.







