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

Share this project:

Updates

Submission history