Case study · Live on the App Store

Rackd

A fitness app that hands you a workout in three taps

A cross-platform fitness app built and run end to end — Flutter client, TypeScript Cloud Functions, Firestore with tested security rules, subscriptions, analytics, and a keyless release pipeline. Five releases shipped and live on the App Store.

Year
2026
Surface
iOS · Android next
Role
Design, build, and operate — every layer
See it
rackdlife.com ↗
Workout catalog, hand-built
425
Releases shipped to the App Store
5
Deploy keys to leak or rotate
0
01

The problem

Why the app exists

Most people do not skip workouts because they are lazy. They skip because they do not know what to do, and every fitness app answers that question with a library to scroll and a program to build. The friction is where the workout dies.

The product bet was that removing the deciding is the whole product: answer two or three prompts — focus, equipment, time — and get something you can start now. That bet only pays if the app is fast, honest about the equipment you actually own, and trustworthy enough to log against for months. All three of those are engineering problems, not design problems.

02

What it looks like

Shipped screens, not mockups
Rackd Home screen — Get started with workouts picked by the team creator
Home opens on what the creator picked, not an empty library, so a new member is one tap from scheduling their first workout.
Rackd Workouts screen — today's pick from the coach's challenge, a shuffle button, and Build one filtered by time and gear
The whole product thesis in one screen: the coach's pick and a shuffle for people who do not want to choose, and a time, gear and focus filter for people who do.
Rackd active workout screen — an AMRAP timer counting down, rounds completed, and the movements to tick off
The timer is format-aware — it counts down for AMRAP and EMOM and up for "for time", so the same screen serves every workout format without a setting.
Rackd progress screen — the weekly goal ring, a streak leaderboard of friends, and recent records
Personal records are detected server-side from logged history rather than entered by hand, which is why the celebration can be trusted.
Rackd Friends screen — friends who trained today, and their recent workouts with kudos and Do it too
Friend activity is visible only to people both sides accepted, and it shipped with the moderation it needs — report, block, and content filtering — because a social surface without one does not clear App Review.
03

How it was built

The decisions that mattered
  1. Ownership-scoped data from the first commit

    Workout logs and personal forks are private by default, and the Firestore collection layout is shaped so an ownership-scoped read is the natural query rather than the careful one. Security rules are version controlled and every rule change ships with a rules test — the tests are what make it safe to keep changing the data model after launch.

  2. Trust boundaries on the server, not the client

    Anything security-sensitive runs in Cloud Functions or in rules, never in the client. Authenticated operations resolve the user from the Firebase Auth context instead of trusting an id the client sent, and App Check gates the callable surface. It is the difference between an app that is private and an app that merely looks private.

  3. Dark launches behind flags

    A full AI coaching surface — its own route, prompt entry, and loading experience — ships inside the binary but disabled by a remote flag, and no store metadata references it. Features land in production dormant and get switched on when the product is ready, which decouples shipping from launching. When the flag platform moved from Remote Config to PostHog, it moved as a seeded config rather than a code change.

  4. A release pipeline with no keys in it

    GitHub Actions builds and deploys through Workload Identity Federation: GitHub mints an OIDC token and Google exchanges it for short-lived credentials. There is no service-account JSON in a secret store, so there is nothing to leak and nothing to rotate — which is also what let the same pattern be reused, unchanged, for the marketing site and for this one.

  5. Cost treated as a design constraint

    Functions carry explicit instance caps, the workout catalog is fetched as a one-shot read rather than a live subscription, and the read pattern was revisited as the catalog grew past 400 documents. Serverless bills for carelessness, and the cheapest time to notice is before the invoice.

  6. A social surface built to clear review

    Teams and contact-based discovery shipped alongside a full moderation stack — reporting, blocking, and content filtering — specifically to satisfy App Review guideline 1.2. Building the moderation with the feature rather than after a rejection is the difference between one submission and three.

04

The stack

All of it, in one place

Client

  • Flutter (Dart)
  • Riverpod
  • go_router
  • freezed

Backend

  • Cloud Functions (TypeScript, 2nd gen)
  • Firestore
  • Cloud Storage
  • FCM
  • App Check
  • Remote Config

Platform

  • GCP / Firebase
  • GitHub Actions
  • Workload Identity Federation

Product

  • RevenueCat subscriptions
  • PostHog analytics + flags
  • Crashlytics
  • Performance Monitoring

Want this run on your product instead of ours?

Send over the shape of the problem and we will come back with an honest read on scope, timeline, and cost — before anyone signs anything.