A React Native mobile app for Zwift racers to browse upcoming events, explore race categories, and predict race results based on participant data.
- 📅 Browse Upcoming Events - View all scheduled Zwift races, group rides, workouts, and time trials
- 🏁 Event Details - See route information, distance, elevation, duration, and participant counts
- 👥 Category Analysis - Explore subgroups (A-E) with specific pace ranges and registered riders
- 📊 Race Prediction - View participants with their racing stats to estimate potential finishing order
- 🔗 ZwiftPower Integration - Direct links to detailed event and rider information
- 🌍 Cross-Platform - Works on iOS, Android, and Web browsers
![]() |
![]() |
![]() |
![]() |
![]() |
- Framework: React Native with Expo (SDK 51)
- Navigation: Expo Router (file-based routing)
- Styling: NativeWind (Tailwind CSS for React Native)
- State Management: TanStack Query (React Query)
- Language: TypeScript
- API Client: Axios
- Package Manager: Bun
- Node.js 18+
- Bun package manager (
curl -fsSL https://bun.sh/install | bash
) - iOS Simulator (Mac only) or Android Emulator
- Expo Go app on your physical device (optional)
# Clone the repository
git clone https://github.com/taehoio/zwift-app.git
cd zwift-app
# Install dependencies
bun install
# Start the development server
bun start
# iOS Simulator
bun run ios
# Android Emulator
bun run android
# Web Browser
bun run web
# Expo Go (scan QR code)
bun start
zwift-app/
├── app/ # Expo Router pages
│ ├── _layout.tsx # Root layout with navigation
│ ├── index.tsx # Home screen (event list)
│ └── events/
│ └── [eventId]/ # Dynamic event routes
├── api/ # API client functions
├── components/ # Reusable UI components
├── types/ # TypeScript type definitions
├── styles/ # Global styles and utilities
├── libs/ # Utility functions
└── assets/ # Fonts and images
# Development
bun start # Start Expo development server
bun run ios # Run on iOS simulator
bun run android # Run on Android emulator
bun run web # Run in web browser
# Testing
bun test # Run tests in watch mode
bun run test:ci # Run tests once (CI mode)
bun run test:coverage # Generate coverage report
# Code Quality
bun run lint # Run ESLint
bun run format # Format code with Prettier
bun run format:check # Check formatting
The app connects to the Zwift API backend at https://zwift.taeho.io/api/v1
with the following endpoints:
GET /events
- Fetch all upcoming eventsGET /events/{eventId}
- Get event details with route informationGET /events/{eventId}/subgroups/{subgroupId}
- Get participants for a subgroup
- Real-time list of upcoming Zwift events
- Event type indicators (race, group ride, workout, time trial)
- Quick view of start times, routes, and distances
- Category badges showing available subgroups
- Detailed participant lists with key metrics:
- FTP (Functional Threshold Power)
- W/kg (Watts per kilogram)
- Racing Score
- ZwiftPower rank and category
- Nationality flags for international competition
- Direct links to ZwiftPower profiles
- Intelligent data refresh with TanStack Query
- Exponential backoff for subgroup details
- Pull-to-refresh on all screens
- Optimized for battery life and performance
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the project
- Create your feature branch (
git checkout -b feature/AmazingFeature
) - Commit your changes (
git commit -m 'Add some AmazingFeature'
) - Push to the branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Built with ❤️ for the Zwift racing community
- Special thanks to ZwiftPower for providing racing data
- Zwift is a trademark of Zwift, Inc.
For issues, questions, or suggestions, please open an issue on GitHub.
Made by taeho.io