NermaLog
Nobody builds this. That's exactly why we did.
Demo video: https://youtu.be/MMFKs68-s9Y
Inspiration
There are polished apps for almost every measurable aspect of human health: sleep, nutrition, fitness, meditation, menstrual cycles - complete with analytics dashboards, trends, and personalized insights.
But intimate life? Silence.
The few apps that exist often treat intimacy as a novelty or hide behind euphemisms, as if tracking this part of life is something to be embarrassed about.
We disagreed.
Intimacy is a fundamental part of being human. It can influence emotional wellbeing, relationship dynamics, and physical health. We believe it deserves the same kind of data-driven self-awareness tools that every other health domain gets.
So we built NermaLog: a serious, privacy-first personal health system for understanding intimate wellbeing through data.
Users can track and analyze:
- Frequency and duration trends
- Partner-specific patterns
- Protection consistency
- STI testing history
- Time-of-day and seasonal patterns
- Menstrual cycle-phase correlations
- Personal health and wellness indicators
This isn't a gimmick. It's an attempt to bring the same rigor we apply to fitness and wellness tracking to an area of life that has historically been ignored.
Privacy by Design
The biggest barrier isn't technical — it's trust.
People may hesitate to store intimate information on their own phone, let alone upload it to someone else's servers. That's why privacy isn't a feature in NermaLog. It's the foundation of the architecture.
- Data is encrypted locally using AES-256 before being stored.
- There is no cloud sync by default.
- Biometric and PIN authentication protect access.
- Stealth mode hides the app from the recent-apps screen.
- Analytics and insights are calculated on-device.
- Cloud backup is strictly opt-in and end-to-end encrypted.
The principle is simple:
Your intimate data belongs to you.
How We Built It
NermaLog is a bare React Native application - no Expo - targeting both iOS and Android.
Architecture
We chose a local-first architecture so sensitive data stays on the device by default.
- React Native 0.84 with the New Architecture enabled
- SQLite via OP-SQLite + SQLCipher for encrypted structured data
- MMKV for encrypted key-value storage
- Zustand for global state management
- Persisted stores for authentication, sessions, partners, health logs, cycle tracking, themes, and language preferences
- Supabase for authentication and optional cloud backup
- RevenueCat for subscription management
Authentication
Authentication supports:
- Email OTP
- Apple Sign-In
- Google Sign-In
The application maintains separate development, staging, and production environments, each with its own:
- Bundle IDs
- Xcode schemes
- Android product flavors
- Environment configuration
On-Device Analytics Engine
One of the core challenges was building meaningful analytics without sending sensitive information to a backend.
Our insights engine runs entirely on-device and calculates:
- Frequency distributions over configurable time periods: 1W, 1M, 3M, 6M, 1Y
- Duration trends and averages
- Protection-rate trends
- Average-gap analysis with trend detection
- Partner frequency breakdowns
- Time-of-day distributions: morning, afternoon, evening, night
- Activity type distributions across nine categories
Menstrual cycle-phase correlations:
- Menstrual
- Follicular
- Ovulation
- Luteal
Milestone tracking and streak calculations
For visualization, we use react-native-gifted-charts combined with custom components, keeping the analytics both private and lightweight.
Health & Wellness Suite
NermaLog includes a wellness scoring system built from three weighted factors:
| Factor | Weight | What It Measures |
|---|---|---|
| Testing Recency | 35 points | When the last STI or health test was taken and its result |
| Protection Consistency | 35 points | Percentage of sessions where protection was used |
| Cycle Regularity | 30 points | Variance in cycle length over time |
Each factor has its own scoring algorithm.
The combined result gives users a 0–100 wellness score that updates as they log more data — a quiet, non-judgmental nudge toward healthier habits.
Health Features
The health module also supports:
- STI and health test logging with date, type, and result tracking
- Partner awareness records for shared test results
- Cycle-phase calendar with automatic phase calculation
- Configurable cycle length and period duration
- Health reminders
- Cycle-phase notifications
Encryption: The Real Challenge
This is where the project pushed us the hardest.
We didn't want encryption to be cosmetic. If someone's intimate history is going to exist in a database - even on their own phone - it needs to be properly protected.
Not "encrypted with a library we found on npm."
Actually engineered.
What We Built
We implemented a full key hierarchy using standard, audited cryptographic algorithms:
| Layer | Algorithm | Purpose |
|---|---|---|
| Root Key (DEK) | CSPRNG | 32 random bytes, never used directly |
| Sub-keys | HKDF-SHA256 | Per-row derived keys bound to table and row ID |
| Encryption | AES-256-GCM | Authenticated encryption with associated data |
| Key Wrapping | AES-256-GCM + Argon2id | Password and PIN protect the root key |
| Local Database | SQLCipher | AES-256 full-database encryption |
Every row synced to the cloud is encrypted individually.
The associated data (AAD) binds each ciphertext to a specific user, table, and row ID - so a row can't be moved, swapped, or replayed without detection.
The server never sees plaintext.
It stores opaque blobs and routing metadata. That's it.
What We Had to Learn
Neither of us had built a real encryption system before.
We went from "AES sounds good" to understanding:
- Why you need a key hierarchy instead of using one key for everything
- How HKDF derives purpose-specific keys from a single root
- What authenticated encryption actually authenticates and why AAD matters
- How Argon2id protects against brute-force attacks on passwords
- Why nonce management matters and when random nonces are safe
- How to zero key material from memory when the vault locks
It was the steepest learning curve in the project - and the part we're most proud of.
Internationalization
NermaLog ships with 10 languages from day one:
English · French · German · Spanish · Portuguese · Russian · Hindi · Japanese · Korean · Chinese (Simplified)
Every user-facing string runs through i18next with proper pluralization rules.
Adding a feature means updating all 10 locale files — no exceptions.
A missing key in any language is treated as a bug.
Challenges
1. Encryption
Covered above.
It was the biggest technical challenge by a wide margin.
Multiple iterations, a lot of reading, and a healthy amount of paranoia.
2. App Store and Play Store Submission
We underestimated this.
Three build environments, separate bundle IDs, code signing for iOS, certificates, provisioning profiles, entitlements, Android signing configurations, 14-day testing period, content-rating questionnaires for a sensitive-category app, encryption export declarations, screenshot requirements, and metadata across multiple fields. We are still under review in both stores and are expected to publicly release any time soon.
The release pipeline is its own engineering project.
3. RevenueCat Integration
The SDK itself is well-built.
The friction lives in the platform configuration:
- Setting up products and entitlements in App Store Connect
- Setting up products in Google Play Console
- Mapping products to RevenueCat offerings
- Handling restore-purchase flows
- Testing subscriptions in sandbox environments
- Supporting subscription behavior across both iOS and Android
4. Making It All Fit Together
Biometric authentication.
Encrypted local storage.
Encrypted cloud sync.
Subscription gating.
Cycle tracking.
Analytics.
10 language translations.
Three build environments.
Two platforms.
In a two-person team over a couple of months.
Every integration touched three other integrations.
The challenge wasn't any single feature.
It was making all of them coexist without breaking each other.
Built With
React Native · Zustand · MMKV · OP-SQLite · SQLCipher · Supabase · RevenueCat · AES-256-GCM · HKDF-SHA256 · Argon2id · react-native-reanimated · react-native-gifted-charts · i18next
Built With
- encryption
- firebase
- kotlin
- mmkv
- react-native
- sqlite
- supabase
- swift
Log in or sign up for Devpost to join the conversation.