KurlClub Gym Management
KurlClub is a gym management SaaS that runs member operations, billing and payments for gym operators. As the primary engineer on the web platform at KurlTech Systems, I owned it end to end, from onboarding to analytics, and later came back to harden it ahead of a major release.
- React
- Next.js
- TypeScript
- Redux Toolkit
- Node.js
- Jest
Particulars
- Client
- KurlTech Systems (in-house product)
- Timeline
- Aug 2024 – Jun 2025, and Feb 2026 – present
- Role
- Primary engineer, full stack
- Users
- 10+ gym operators, 50+ end users
- Scope
- Members, billing, payments and analytics
Note: Some implementation details are omitted for confidentiality. This case study covers my role, public product behaviour and general architecture only.
Record summary
10+
Gym operators
50+
End users
30%
Faster admin tasks
40%
Fewer API requests
01The mandate
Gym operators juggle memberships, renewals, outstanding dues and attendance every day. KurlClub puts all of it in one place: a dashboard that tells an owner who has paid, who is overdue and who is about to lapse as soon as they sign in.
Real gyms ran their front desks on the product, so every improvement had to land without disrupting the operators who depended on it.
02What I owned
I was the primary engineer on the React and Next.js platform across billing, payments and analytics. I owned features end to end: shaping the UI, designing component APIs, wiring REST endpoints, and tracing problems through to the backend services when they crossed layers.
In my second stint I returned to stabilise core modules before a major release. I expanded Jest coverage across new features while holding 75%+ overall, led validation of onboarding and subscription workflows, and ran regression passes to catch release blockers before production.
03What the platform covers
- Member records, membership plans and renewals, with upcoming expiries surfaced up front.
- Payments and outstanding dues, with paid, partial and unpaid states at a glance.
- An operator dashboard covering total members, outstanding payments, irregular attendees and expiring plans.
- Guided onboarding for new gyms and administrators.
- Billing and payment analytics for gym owners.
04Rendering and caching, backed by benchmarks
I redesigned the onboarding workflow and moved key pages to server-side rendering, so administrators saw real data on first paint rather than a loading state. Together those changes cut administrator task completion time by 30%.
On the client, I benchmarked React Query against Redux-based caching for the app's access patterns before committing, then shipped the Redux Toolkit approach. It removed 40% of unnecessary API requests. Underneath sits a library of 20+ reusable components built with TypeScript generics and utility types, so prop mismatches fail at compile time.
Fig. 01
05Working flow
What happens when an administrator opens the dashboard and moves around the app: server rendering for the first paint, then the client cache keeps repeat requests off the network.
Fig. 02
01 Opens the dashboard
02 Fetches members, dues and expiries server-side
03 Records as JSON
04 Page rendered with real data on first paint
05 Navigates to Members or Payments
- 06 Serves cached state, skips duplicate requests
07 Refetches only what is missing or stale
08 Fresh records
09 Screen updates without a full reload
06The life of a membership
- 01
Onboard the gym
An operator sets up the gym and its administrators through the guided onboarding flow.
- 02
Enrol a member
A member joins on a plan, and the record carries their start date and renewal cycle.
- 03
Collect payment
Payments are recorded as paid, partial or unpaid, and anything outstanding rolls into dues.
- 04
Track dues and attendance
The dashboard flags outstanding payments and members who have stopped showing up.
- 05
Renew or lapse
Plans nearing expiry are surfaced in advance so the front desk can follow up before a member drops off.
07Hard parts
- Changing the rendering strategy of live pages without breaking operators' daily workflows.
- Choosing a caching layer on benchmarks rather than habit, then migrating to it incrementally.
- Designing generic, typed components flexible enough for every module but strict enough to catch misuse.
- Holding 75%+ coverage while new features landed quickly ahead of a major release.
- Defects that crossed UI, REST APIs and browsers, which needed someone comfortable at every layer.
08Outcomes
- Administrator task completion time down 30% after the onboarding redesign and SSR migration.
- 40% fewer unnecessary API requests from Redux-based state caching.
- 20+ reusable typed components that kept new modules consistent.
- Better discoverability through semantic HTML and structured metadata on key pages.
- A release hardened by structured regression testing and 75%+ Jest coverage.
09How I approached it
- 01
Measure before choosing
Benchmarks, not opinions, decided the caching layer.
- 02
Optimise for the operator's time
The metric that mattered was how long an admin task took.
- 03
Let the types review the code
Generic components caught mismatches before a reviewer had to.
- 04
Own the release, not just the feature
Coming back for a second stint meant owning the quality of what shipped.
Related work
More projectsHR Platform
Enterprise HR, React, Node.js, JWT
BFC Pay
FinTech, React, Node.js, Rust
HI5 Overseas
Client application, Next.js, TypeScript, Node.js
Subscriptions
SaaS platform, React, Node.js, Express