A privacy-first mood tracker built with React Native and Expo.
All data stays on your device. No accounts, no cloud, no tracking.
|
Mood Tracking
Activities
|
Statistics & Insights
Customization & Privacy
|
Android: SoulSync is on the Google Play Store. Nothing else to set up, no account, no sign-in.
Prefer installing outside Play? Grab the latest signed APK from the GitHub Releases page and sideload it.
Enjoying SoulSync? A Play Store review helps a tiny open-source project a lot.
git clone https://github.com/Antimatter543/mood-tracker.git
cd mood-tracker/frontend && npm install
npx expo startScan the QR code with Expo Go, or press a / i for an emulator. The app is plain CNG with no custom native modules, so Expo Go runs it faithfully (new architecture, gesture-handler, reanimated, and SQLite all bundled or pure-JS). Release builds are produced in the cloud via EAS Build and GitHub Actions CI; update the projectId in app.json after forking.
| Layer | Technology |
|---|---|
| Framework | React Native 0.85 + Expo (SDK 56), new architecture (Fabric) |
| Routing | Expo Router (file-based) |
| Animation | Reanimated 4 |
| Database | SQLite (local, on-device) |
| Charts | react-native-chart-kit |
| Calendar | react-native-calendars |
| Language | TypeScript 6 (strict mode) |
Project Structure
frontend/
├── app/ # Screens (file-based routing)
│ ├── (tabs)/
│ │ ├── index.tsx # Home dashboard
│ │ ├── timeline.tsx # Entry history/journal
│ │ ├── stats.tsx # Analytics & visualizations
│ │ ├── insights.tsx # Plain-language insights from your data
│ │ └── settings.tsx # App settings (themes, reminders)
│ └── _layout.tsx # Root layout (DB provider, themes, reminder re-arm)
├── components/
│ ├── forms/ # Entry form, mood selector, activity + photo picker
│ │ └── hooks/ # useEntryDraft, useMoodScale
│ └── visualisations/ # Charts, heatmap, calendar
│ └── transforms/ # Pure data transforms (fully tested)
├── context/ # React contexts (data, settings, timeframe)
├── databases/ # SQLite facade, migrations, CRUD modules
│ ├── dateHelpers.ts # Pure local-tz date math
│ ├── mediaHelpers.ts # On-device photo file storage
│ ├── entry-media.ts # Photo attachment CRUD
│ └── migrations.ts # Auto-run schema migrations
├── lib/
│ └── notifications.ts # Local daily-reminder scheduling (pure + testable)
└── styles/
└── global.ts # Theme definitions
| Metric | Status |
|---|---|
| Test suites | 65 passing |
| Tests | 603 passing |
| TypeScript | strict: true, tsc --noEmit clean |
| Lint | expo lint zero errors |
| Pre-commit | npm run check (typecheck + lint + tests) |
The database layer, chart transforms, form hooks, and date helpers are pure-function modules with dedicated test files.
npm test # Run all tests
npm run check # Full pre-commit gate| Table | Purpose |
|---|---|
entries |
Mood entries (score, notes, timestamp) |
activities |
User-defined activities with icons |
activity_groups |
Activity categories |
entry_activities |
Entry-activity links (many-to-many) |
entry_media |
Photo attachments (file path + type, on-device) |
user_settings |
Key-value settings store |
Migrations run automatically on app launch via databases/migrations.ts.
Known Issues
- Settings loader shows indefinite spinner if SQLite load fails (needs timeout/fallback)
Planned
- CSV/PDF export
- AMOLED dark theme
- Photo attachment cloud-free encrypted backup
- Biometric app lock
- Fork the repo and create a feature branch
- Make changes, then run
npm run check(typecheck + lint + tests) - Open a Pull Request
Tips: Dev-only features appear when __DEV__ is true. Add tabs by creating files in app/(tabs)/. Themes live in styles/global.ts. Database changes go through databases/migrations.ts.
Built with care. Your data never leaves your device.
