Predicting how the next day will feel.

Moon Quest is a mobile app for people living with PMDD, PME and severe PMS. It forecasts how the days ahead will feel rather than recording what already happened.

Client
Moon Quest
Service
Design and Development
Year
Moon Quest
A crescent moon low in a clear night sky above a quiet horizon.

Background

Helene Choo is a storyteller, marketer and women’s health advocate with a decade in brand strategy behind her, and for more than ten years she lived with PMDD that nobody had named. A diagnosis finally came in 2023, and most people with the condition wait that long. Her story of getting there is the reason Moon Quest exists.

The app is a guide for people living with PMDD, PME and severe PMS. It forecasts how the days ahead are likely to feel from where someone is in their cycle, across seven measures aligned to the Daily Record of Severity of Problems, a validated instrument used in premenstrual research, and it presents that as a daily reading rather than a chart to interpret. The product is supportive rather than diagnostic, and it says so plainly to the people who use it.

WeaveLines worked with Helene from the first product decisions to the release on both stores. What follows is how the product took shape.

Research

Most cycle apps look backward

The work began with a close look at the cycle apps already on the market. Nearly all of them are trackers. They record what has already happened, they reward unbroken streaks, and they have little to say about the day ahead, which for someone with PMDD is the day that matters.

PMDD is cyclical by definition. The hard days tend to arrive in a pattern, which means they can be anticipated, and anticipation is worth more than documentation to the person bracing for them. That finding became the product goal. Moon Quest would treat the forecast as the product rather than as a feature inside a log, and it introduces itself as the first cycle app that isn’t a tracker. No streaks, and no guilt for the days nobody checks in.

That one decision shaped everything after it, from the architecture to the model to the interface, and it is the reason the app opens on a prediction rather than on a calendar.

Challenge

Being useful before it knows anything

A forecast carries a problem a log does not. It has to be useful on the very first day, before the user has recorded anything at all, and it has to grow more accurate with use without ever appearing to have been guessing at the start.

The app also had to work in the moments it exists for. Someone reaching for it on a difficult evening should not need a connection or an account to see their forecast.

Our solution

We took Moon Quest from a prototype shaped with Helene to an app released on both stores. The engagement covered product design, the prediction model, the mobile application, the content platform and the backend behind them.

  1. 01Product Design

    A working prototype iterated quickly with Helene until it matched her vision, then documented for the build.

    Read more
  2. 02The Forecast

    Population baselines give a new user a real forecast on day one, and Kalman filters make it theirs as they check in.

    Read more
  3. 03Local-first Architecture

    Every read and write hits a local database first, so the app works fully offline and an account is optional.

    Read more
  4. 04The Avatar

    A single Rive file carries ten expressions and full customization, bound to live data rather than drawn state by state.

    Read more
  5. 05Learning and Progress

    Content is authored in a web dashboard and read offline on the device, with a progress loop that ends at the avatar.

    Read more
  6. 06Subscriptions and Access

    A subscription bought before signing in follows the person to the account they create afterwards.

    Read more
  7. 07Platform and Release

    One TypeScript monorepo behind an iOS app, an Android app, an admin application and a serverless API.

    Read more
  • The Moon Quest home screen on day seven, showing the avatar above the word Great and the follicular phase, with a Learning about you card reading fifteen percent personalized
  • The Moon Quest Insights tab showing a Sensory Overload card ready to begin and a progress card at the Star Gazer level
  • The Moon Quest avatar editor with the Right Hand tab open, a journal selected, and accessories priced in Moon Points
The daily forecast, the insight that unlocks with it, and the avatar the progress loop pays into.

01Product Design

Fast iterations toward her vision

The prototyping and design were done in Replit, in fast iterations. We improved and changed the design based on Helene’s feedback, and each round closed the distance between the prototype and the product she had in mind.

In some meetings the adjustments happened live. A flow could be changed and judged on the spot, so decisions were made looking at the real thing rather than imagining it from a description. Iteration that cheap changes the conversation, because trying an idea costs minutes and discarding it costs nothing.

Once the shape of the product was settled, it was written down. Specifications and PRD documents were produced from the validated design, so implementation started from a documented source of truth rather than from memory of what had been agreed.

02The Forecast

Useful on day one, personal by month three

The forecast had to work immediately and improve from there. We built it in two parts.

The first is a set of population baselines. Before a user has recorded anything, each of the seven measures is predicted from documented patterns on the same one to six severity scale the app uses, shaped by its own curve for each phase of the cycle. A new user sees a real forecast rather than an empty state.

The second is personalization. Seven independent Kalman filters, one for each measure, learn two numbers about the person using the app. The first is their baseline, the level they sit at normally. The second is their amplitude, how strongly they react as the cycle moves toward the late luteal phase. A prediction is the baseline plus the amplitude scaled by where they are in the cycle. Three genuinely different people, one who barely changes across the month, one who spikes sharply in the final week and one who runs elevated throughout, are all served by the same equation with no special cases.

Cycle length is predicted on its own terms. Bayesian inference treats what the user reported during onboarding as a starting position and shifts weight toward their recorded history as cycles accumulate, so the prediction stays sensible at zero recorded cycles, at one and at ten.

Built into the model

An honest confidence figure

The personalization percentage on the home screen is the number the model actually uses. It is computed from how much of each cycle phase the user has checked in for, and that same value decides how far the forecast leans on learned weights rather than population data. The interface cannot show a confidence the model is not acting on.

Curves matched to the phase

Each phase interpolates differently, falling away through menstruation, holding flat through the follicular phase, rising at ovulation and rising more steeply through the luteal phase, matched to documented symptom patterns.

Entirely on the device

The whole model runs locally against local data, with no request to a server and nothing to wait for.

  • Barely changes

    A low baseline and a small amplitude. The forecast stays close to flat all month.

    61Day 1Day 28
  • Spikes in late luteal

    A low baseline and a large amplitude. Calm for three weeks, then a steep rise.

    61Day 1Day 28
  • Elevated throughout

    A high baseline and a moderate amplitude. Raised all month, higher at the end.

    61Day 1Day 28
  • This person’s forecast
  • Population baseline
  • Late luteal
Predicted severity across one cycle, on the same one to six scale the app uses. All three come from the same equation. Only the baseline and the amplitude differ, and both are learned per person from their own check-ins.

03Local-first Architecture

A local app that can optionally sync

Moon Quest is not an online app with an offline mode. It is a local app that can optionally sync.

Every read and write goes to a local database on the phone first. Writes are ordinary synchronous functions with no loading state, and reads are live queries that update as the data changes. Nothing in the interface waits on the network.

The detail that makes the account model work is that the local database stores no user id. A record written before signing in is identical to one written after. When someone does sign in, everything still marked as pending is pushed and the server stamps ownership from the authenticated session. Signing out stops the sync and leaves the local data untouched. Someone can use the app for months without an account and keep every day of it when they create one, with no migration step and nothing at risk.

Where sync usually goes wrong

Ordering

Records are pushed in an order that respects their relationships, with period logs first because cycle detection depends on them, and deletions last.

Deletions

A deletion writes a tombstone that syncs and removes the record remotely, so a deleted day cannot reappear on the next pull.

Failure

Anything that fails goes to a persistent retry queue with exponential backoff across five attempts, rather than being lost or retried forever.

Timing

The engine runs on events rather than background tasks. A local write schedules a push three seconds later, returning to the app triggers a pull followed by a push, and signing in triggers a full synchronization.

After the prediction engine, this is the most heavily tested part of the app.

04The Avatar

One Rive file, bound to live data

The avatar is how the app communicates emotional state, and it is a single Rive file driven by data binding rather than a set of drawn states.

The face reflects the day’s reading. Ten expressions run from grounded and content through strained and overwhelmed to distressed and in need of care, mapped from the emotional load the model computes and set at runtime.

Customization is bound live rather than baked in. Hair, outfit, pose and accessories are enumerations in the Rive file, and skin, hair, socks, shoes and the colors of individual items are color bindings. Changing a color in the editor updates the running artboard directly.

One file serves two purposes. A full artboard drives the editor and a head-only artboard drives compact places such as the mood calendar, so there is no second asset to keep in step.

Inclusivity is part of the rig rather than an addition to it. A wheelchair pose is a first-class option alongside the standing pose, and the color ranges were revised specifically to widen who the avatar can look like.

  • A standing avatar with long black hair and a fringe, wearing a coral overall over a pale yellow tee with green shoes
  • A standing avatar with short red hair and fair skin, wearing a brown dress with yellow socks and black shoes
  • A standing avatar with dark skin wearing a blue headscarf and a black dress, holding a small blue journal
  • An avatar with long wavy brown hair and a coral tee, seated in a wheelchair
Four avatars from the same Rive rig. Skin, hair, outfit, pose and accessories are all live bindings rather than separate artwork.

05Learning and Progress

Authored on the web, read on the device

Lessons and insights are authored in a web dashboard, pulled by the mobile app and written into the local database so they can be read with no connection. New content can be published at any time without an app release, and the app checks for it against a daily freshness stamp rather than fetching on every launch.

Completing an insight earns Moon Experience, which raises a level, and Moon Points, which buy avatar accessories. The progress loop ends somewhere the user already cares about, which is the avatar they have made their own.

06Subscriptions and Access

A purchase that follows the person

Access runs on a subscription entitlement, which creates a problem worth naming. Someone can subscribe before they ever sign in, which means the purchase belongs to an anonymous identity and the account arrives afterwards. Transfer, expiration and purchase webhooks reconcile the two behind signature verification, so the subscription follows the person rather than the installation.

Promotional codes can also be issued from the admin application, either as lifetime grants or capped at a fixed number. A redemption counter with optimistic concurrency control means a capped code cannot be over redeemed when several people submit it at the same moment.

07Platform and Release

One codebase behind four surfaces

Work began in December 2025, and Moon Quest shipped in March 2026 on the App Store and Google Play, from one TypeScript codebase built with Expo and React Native.

Three applications and six shared packages sit in a single monorepo. The API is written in Hono and deployed as one serverless function, the database is Postgres through Drizzle, and authentication runs on Apple and Google sign in.

How the platform holds together

One typed API for three consumers

The API exports its own type, and the mobile app and the admin application both call it through a typed client. A change to a route becomes a compile error rather than a failure someone finds in production.

Deployments that skip themselves

Continuous integration inspects what a change actually affects and skips the server deployment entirely when the server is untouched.

Errors visible in production

Exceptions are captured on both the server and the device, with source maps uploaded at deploy time so a report points at real code.

Privacy taken seriously

Local records carry no user id, health-related data was removed from analytics, and environment variables are validated rather than read directly.

Early users have called the product intuitive, friendly and supportive, and the in-the-moment breathing and grounding exercises, which we proposed, have been especially well received.

Keywords

  • Product design
  • Prototyping
  • Mobile development
  • Backend development
  • React Native
  • Expo
  • TypeScript
  • SQLite
  • Offline-first
  • Rive
  • Hono
  • Postgres
  • Drizzle

WeaveLines’ proactivity in thinking about the project not just in terms of app development but also for the monetization, business, and UX/retention aspects has been impressive.

Helene Choo, Founder of Moon QuestRead the full review on Clutch

More case studies

  • Party games that do good.

    Goin Out Games sells real-world party card games where scanning a card lets guests push a charity up a live leaderboard. We built its storefront and game platform on headless Shopify and Next.js.
    Read more
  • Streamlining operations in the hospitality industry.

    Hotlas is an integrated inventory and orders management solution for restaurateurs and bar managers.
    Read more

Get in touch with us

Tell us about your product and your plans. We will come back with a clear view of what it would take and how we would approach it.

Contact us

Our offices

  • HeadquartersWeaveLines LLCrue Slah Eddine Bouchoucha2026 Sidi Bou SaidTunis, Tunisia
  • Tunis OfficeWeaveLines LLC39 rue Ibn Khaldoun1002 Tunis, Tunisia