---
title: "JustGains Case Study"
description: "How JustGains had Strava activities in its workout feed in a day on a self-hosted Open Wearables fork, then added routes and elevation profiles itself."
canonical_url: "https://openwearables.io/case-study/justgains"
---

# How JustGains puts every run, ride and rep in one feed.

Case study

[JustGains, their site](https://justgains.com/)

JustGains is an open social workout platform where lifting and cardio share one feed and one history. Open Wearables brings in what members' watches already recorded, and being open source let the team build on top of it.

[Get started](https://openwearables.io/docs/quickstart) [Book a demo](https://openwearables.io/book)

To Strava in the feed

1 day

Engineer on the integration

1

Countries with members

58

Platforms: iOS, Android and web

3

The problem

## Their training was already being recorded. Just not by JustGains.

A run lives in Strava, a ride on a Garmin, a gym session in JustGains. Asking people to record everything twice is how you lose them.

### One complete history

Every run, ride, swim and hike lands in JustGains automatically, next to the lifting.

### Routes as a real feature

Not “you ran 8 km”, but the GPS line itself, to draw, share, replay and rank.

### No duplicates

When a watch and the app record the same session, members see one activity with the best data from each.

The integration

## One integration, every provider.

One engineer did it, from the first sync to a fork they now extend themselves.

01

### Connect through Open Wearables

OAuth, tokens, provider quirks and webhook delivery were already solved, so the first provider was in the feed within a day.

02

### Self-host it next to their stack

Their fork runs alongside the rest of their infrastructure, with Postgres, Redis and signed webhooks.

03

### Wire it into their API

One service class holds all of it: activities arrive by webhook, with an hourly sync as a safety net, into one normalised record.

04

### Reconcile and extend

Watch activities link to the gym workout they overlap, duplicates fold into one, and what the product needed next went into their fork.

What surprised them

## The hard parts were already solved.

### How quickly it became real

OAuth, tokens, provider quirks and webhook delivery were already solved.

### How readable the codebase is

When they needed something new, they found the place and added it.

### How little glue they needed

One service class and one webhook controller hold all of it.

In their words

> “With Open Wearables we had Strava activities flowing into the JustGains feed in a day. When we needed route data it didn't return yet, we didn't wait on a vendor: we read the code, added it to our fork, and shipped. That is the difference open source makes.”

James Greene Founder & Engineer, JustGains JustGains logo

[justgains.com](https://justgains.com/)

The deciding factor

## Open source was the deciding factor.

Routes are the heart of their cardio product, and Open Wearables did not keep a Strava workout's route or name yet. With a closed aggregator that ends the conversation. They read the code and added it to their fork.

Commits of their own

7

Files changed

44

Lines added

2,496

Additions, all additive

4

### Routes and names

Every synced workout keeps its GPS line and its title, not just its distance.

### Instant webhooks

A five-line fix so workout.created fires straight away for a single new run.

### Elevation profiles

Up to 300 points per activity, low and high preserved, with tests and docs.

### Their deployment

Configs, a deploy script and a guide for the whole stack on their host.

The stack

## One service class away from every device.

### Providers

OAuth and provider webhooks. Strava is live; Garmin, Polar, Suunto, Oura, WHOOP and Fitbit run through the same pipeline.

### Their Open Wearables fork

Self-hosted on Fly.io: API, Postgres and Redis, Svix webhooks, and their own additions for routes and elevation.

### The JustGains API

.NET on Postgres. One service class is the only Open Wearables code; sync and reconciliation sit beside it.

### The apps

iOS, Android and web: the activity feed, training history, routes, leaderboards and replays.

In the app

## A synced run becomes a route.

Cardio recorded anywhere sits next to the lifting, and the GPS line becomes something members can open, run and compete on.

### Synced from Strava

Route, distance, climb, pace and energy, with where it came from on every activity.

A hike synced from Strava in JustGains, with its map and stats

### Becomes a route

Follow it, export GPX, race the leaderboard.

The same hike saved as a route in JustGains: Follow & record, Save route, Export GPX and a leaderboard

### Replay

A flyover of an activity JustGains never recorded itself.

A flyover replay of the hike in JustGains, 2.44 km into the route

JustGains' Connected Apps with every supported provider connected: Garmin, Polar, Suunto, WHOOP, Strava, Oura and Fitbit

The result

## Connect once. Then forget about it.

Connected Apps lists whatever their Open Wearables instance has enabled. A member taps a provider, approves it, and activities start arriving on their own: by webhook, with an hourly sync as a safety net.

### Strava is live for all members today.

Activities, routes, heart rate, calories and elevation flow into the feed, history, routes and leaderboards. The other providers already run through the same pipeline and are turned on as each is verified.

What's next

## Where they want to take it.

### More providers

Garmin, Polar, Oura, WHOOP, Suunto and Fitbit already run through the same pipeline, turned on as each is verified.

### Recovery into training

Sleep, HRV and readiness shaping what the workout engine suggests for the day.

### Coaching

Coaches see a client's full picture, including what their watch recorded between sessions.

### Contributing back

Upstreaming routes, names, elevation profiles and the webhook fix.

## Build on top of it, not around it.

JustGains started from the public repository, forked it and shipped their own additions. Clone it and run it yourself, or see what it costs to have us stand it up inside your account.

[Get started](https://openwearables.io/docs/quickstart) [See pricing](https://openwearables.io/pricing)

FAQ

## Questions this raises.

### Did JustGains have to fork Open Wearables?

They chose to. Routes were missing for their product, so they added them to a fork with every change additive, and they merge upstream releases into it, most recently 0.6.3. They plan to contribute their additions back.

### How do they stop the same workout appearing twice?

Their activity record is idempotent on the provider and its external id, and a reconciliation step links a watch activity to the gym workout it overlaps, folding cross-source duplicates into one.

### Which providers are live?

Strava is live for all members. Garmin, Polar, Oura, WHOOP, Suunto and Fitbit already run through the same pipeline and are being turned on as each is verified.
