Застосунок для пошуку спортивної тусовки у своєму місті — як ми зробили Sportouch
В індустрії я працюю 6 років, обіймаю позицію Software Engineer, і більшу частину професійного життя присвятив розробці на JavaScript і TypeScript. Маю досвід роботи з C++, C#, а також Dart (Flutter), що дозволило мені розширити технічний кругозір.
Обожнюю дізнаватися щось нове і постійно вдосконалювати свої навички, а ще — займатися спортом, що допомагає тримати баланс між роботою та життям. Рік тому я відкрив для себе React Native і вирішив за допомогою нього вирішити дві власні проблеми: спростити пошук спортивних подій та водночас набути практичного досвіду з цією технологією.
Проблема
Усе почалося з простого питання:
«З ким зібратися у волейбол на вихідних?»
Ми з другом (і колегою за сумісництвом) любимо і займаємося спортом, але досить часто стикаємося з труднощами: все хаотично, рандомно й незручно — особливо гостро це відчувається, коли просто хочеш вийти на поле сьогодні ввечері. До того ж події розкидані по Telegram-чатах, Instagram-сторіз або просто губляться серед десятка, а то й сотень банерів і афіш.
Ідея
Ми вирішили створити не чергову соцмережу або фітнес-застосунок, а утиліту — простий мобільний застосунок, що допоможе:
- швидко знайти спортивні події поруч;
- знайти гравців аби доформувати команду;
- приєднатися до існуючої гри;
- або створити свою.
Sportouch — це рішення як для організаторів спортивних івентів, які хоч раз стикалися з проблемою браку гравців для проведення гри чи тренування, так і для соло-гравців без своєї сформованої команди.

Для кого
Наша цільова аудиторія:
- любителі спорту, які хочуть грати;
- аматори, що не мають стабільної команди;
- організатори локальних активностей.
Ключова цінність — простота. Ти відкриваєш застосунок, бачиш карту з івентами поруч, приєднуєшся до існуючої гри або створюєш свою. Все. Ніяких зайвих рухів. Ніякого хаосу.
Від ідеї до релізу
Ми стартували у вересні 2024 року. Над продуктом працювали невеликою, але сильною командою спеціалістів: розробка, архітектура, дизайн, тестування, ASO — усе робили самостійно.
Реліз у сторах відбувся в травні 2025 року.
Чому не MVP за місяць? Бо ми одразу вирішили, що хочемо зробити core-функціональність зручною, стабільною й масштабованою.
Архітектура та стек
📱 Фронтенд
- React Native + Expo 52: забезпечує швидку розробку та кросплатформність завдяки спільній кодовій базі для iOS та Android. Expo спрощує налаштування, оновлення (expo-updates) та інтеграцію модулів, таких як expo-image, expo-location, expo-notifications тощо.
- Кешування та управління станом: використовується @tanstack/react-query з @tanstack/query-async-storage-persister для ефективного кешування запитів та @react-native-async-storage/async-storage для локального зберігання даних.
- UI та компоненти:
- @rneui/base та @rneui/themed для створення адаптивного та стильного інтерфейсу, що відповідає гайдлайнам iOS та Android.
- @gorhom/bottom-sheet для модальних вікон та react-native-gesture-handler для плавної взаємодії з жестами.
- react-native-calendars та react-native-ui-datepicker для зручної роботи з календарями.
- react-native-maps для інтеграції карт та supercluster для кластеризації маркерів.
- Навігація: expo-router для гнучкої та ефективної навігації в застосунку.
- Діп лінкінг: expo-linking забезпечує підтримку глибоких посилань (deep linking) та універсальних посилань (universal links), дозволяючи відкривати застосунок за допомогою спеціальних URL-схем для переходу до конкретних екранів чи контенту.
- Локалізація: i18next та react-i18next для підтримки багатомовності з інтеграцією через expo-localization.
- Аутентифікація та аналітика:
- @react-native-google-signin/google-signin та expo-apple-authentication для автентифікації.
- @react-native-firebase/analytics та crashlytics для трекінгу подій та моніторингу помилок.
- Додаткові можливості:
- react-native-gifted-chat для чат-функціоналу.
- socket.io-client для реального часу комунікації.
- expo-image-picker, expo-clipboard, expo-contacts для роботи з медіа, буфером обміну та контактами.
- Оптимізація та інструменти розробки:
- react-native-reanimated для плавних анімацій.
- eslint-config-expo, prettier, typescript для забезпечення якості коду та типізації.
- react-native-svg-transformer для роботи з SVG.
⚙️ Бекенд
Сучасна, масштабована та високопродуктивна бекенд-архітектура, побудована на основі NestJS із Fastify як основним HTTP-рушієм, що забезпечує швидкість і ефективність обробки запитів. Використовується модульна структура для легкої підтримки та розширення функціоналу, з акцентом на безпеку, моніторинг і обробку даних у реальному часі.
Основний стек та фреймворки
- NestJS: модульний фреймворк на базі TypeScript із підтримкою Fastify через @nestjs/platform-fastify для швидкої обробки запитів. Використовуються модулі @nestjs/common, @nestjs/core, @nestjs/config для управління конфігурацією та @nestjs/mapped-types для типізації DTO.
- Fastify: високопродуктивний HTTP-сервер із підтримкою @fastify/multipart для обробки файлів і @fastify/static для статичних ресурсів.
- TypeScript: забезпечує строгу типізацію для підвищення якості коду та зменшення помилок.
База даних та кешування
- Postgres + PostGiS: найпопулярніша СУБД та розширення для роботи з геоданими.
- Prisma: потужний ORM для роботи з базами даних, що забезпечує зручне створення запитів і міграцій із типобезпечним доступом до даних.
- Redis (ioredis): використовується для кешування через cache-manager та як сховище для @nestjs/throttler-storage-redis для обмеження частоти запитів.
- BullMQ через @nestjs/bullmq: асинхронна обробка черг для виконання фонових завдань, таких як відправлення повідомлень чи обробка великих даних.
Аутентифікація та безпека
- JWT (@nestjs/jwt): забезпечують безпечну аутентифікацію за допомогою JSON Web Tokens.
- @nestjs/throttler: обмеження частоти запитів для захисту від DDoS-атак та зловживань.
Обробка файлів та медіа
- AWS S3: для зберігання та управління файлами, такими як зображення чи документи.
- NSFWJS з @tensorflow/tfjs-node: для автоматичної модерації контенту, зокрема виявлення неприйнятних зображень.
Комунікація в реальному часі
- Socket.IO (@nestjs/platform-socket.io, socket.io): забезпечує двосторонню комунікацію в реальному часі для чатів, сповіщень і оновлень.
- Twilio, Kyivstar API, Telegram API: інтеграція для відправлення SMS-повідомлень та інших комунікаційних функцій.
- Expo Server SDK: для надсилання push-сповіщень у мобільні застосунки.
Геолокація
- ngeohash: для ефективного кодування та пошуку геолокаційних даних, що використовується для рекомендацій на основі розташування.
Моніторинг та аналітика
- Sentry: моніторинг помилок і продуктивності в реальному часі.
- Prometheus (@willsoto/nestjs-prometheu, prom-client): збір метрик продуктивності для моніторингу серверів.
- @nestjs/terminus: моніторинг стану сервера (health checks) для забезпечення високої доступності.
API-документація
- Swagger (@nestjs/swagger, swagger-themes): генерація інтерактивної документації API з підтримкою кастомних тем для зручного тестування та інтеграції.
Планування та автоматизація
- @nestjs/schedule: для виконання запланованих завдань (cron jobs) та автоматизації процесів.
🔌 Інтеграції
- Google Maps API — для відображення івентів на карті, геокодування.
- Firebase Cloud Messaging — push-нотифікації.
- Firebase Analytics — аналітика застосунку.
- Sentry — трекінг помилок.
- Expo Insights + Google Analytics — аналітика.
- Grafana, Prometheus — моніторинг та метрики.
- RevenueCat — керування підписками та інтеграція оплати.
Особливості архітектури
Проєкт побудований на Feature-based архітектурі з елементами компонентно-орієнтованого підходу, що забезпечує модульність, перевикористання та кросплатформність. Основні особливості:
- Модульна організація: код структурований за функціональними модулями (наприклад, auth, chat, maps, calendar), де кожен модуль містить власні компоненти, логіку та запити до API. expo-router (~4.0.21) підтримує файловий роутинг, що спрощує прив’язку маршрутів до функцій.
- Компонентно-орієнтований UI: використовуються перевикористовувані компоненти через @rneui/base та @rneui/themed (^4.0.0-rc.x) для створення адаптивного інтерфейсу, що відповідає гайдлайнам iOS та Android. @gorhom/bottom-sheet (^5.0.5) і react-native-reanimated (~3.16.1) забезпечують плавні анімації та інтерактивність.
- Ефективне управління даними: @tanstack/react-query (^5.51.23) з @tanstack/query-async-storage-persister та @react-native-async-storage/async-storage (1.23.1) забезпечують швидке кешування та офлайн-доступ до даних.
- Кластеризація та продуктивність: react-native-maps (1.18.0) з supercluster (^8.0.1) та use-supercluster (^1.2.0) забезпечують ефективну кластеризацію маркерів на картах, що зменшує навантаження на слабкі пристрої та оптимізує рендеринг великих наборів даних.
Ця архітектура забезпечує модульність, легке масштабування та високу продуктивність навіть на пристроях з обмеженими ресурсами чи слабким інтернет-з’єднанням.
Юзер флоу
- Користувач завантажує застосунок.
- Авторизується через OTP або Google/Apple ID.
- Вказує своє місто або дає застосунку доступ до гео.
- Бачить події поблизу.
- Може долучитися або створити свою подію.
- Отримує пуш-нагадування за кілька годин до старту.
Оплата — тільки поза застосунком (за домовленістю між учасниками та організатором).

З якими викликами стикнулися
1. Android — пекельний UI
Кожна оболонка (Samsung, Xiaomi, Pixel) рендерить компоненти по-своєму. Стилі з’їжджали. Додали UI-фікси через Platform.select, підключили QA-фрілансера на 10+ пристроях.
2. Apple Developer Account
Apple відхиляв акаунт 4 місяці через бюрократію. Найняли консультанта, який допоміг подати правильний пакет документів.
3. Інтерактивна карта
Google Maps API важкий і дорогий. Події починали «плисти» при масштабуванні. Реалізували кластеризацію на бекенді через PostGIS, обмежили частоту оновлень, але довелось перенести кластеризацію на клієнт, залишивши на бекенді ефективне кешування для ігор відносно мапи світу.
4. Несумісність бібліотек
Деякі пакети для React Native/Expo конфліктували (особливо пуші та deeplinks). Замінювали залежності, рефакторили імпорти, вручну тестували кожну фічу.
5. Оплата
Спочатку було заплановано зробити через LiqPay, але дуже швидко ця ідея перемістилась у смітник, оскільки Apple потребує In-App Purchase. Довелось інтегрувати RevenueCat, що було невеличким викликом.
6. Обмежена команда та тайм-менеджмент
Невелика команда означала, що кожен учасник виконував кілька ролей одночасно: розробка, дизайн, тестування, комунікація з користувачами. Це призводило до перевантаження та затримок у спринтах, особливо коли виникали непередбачені технічні проблеми, як-от несумісність бібліотек чи баги на Android.
Ми навчилися краще розподіляти завдання, використовуючи інструменти на кшталт Notion для планування, але на ранніх етапах брак чіткого тайм-менеджменту коштував нам кількох тижнів затримки.
7. Недостатнє залучення користувачів на старті
Ми недооцінили важливість раннього просування та залучення бета-тестерів. Після релізу ми отримали відгуки, які могли б виявити ще на етапі прототипу, наприклад, щодо незручного UX для створення подій чи недостатньої інтуїтивності фільтрів. Це змусило нас швидко випускати оновлення, що додавало тиску на команду. У майбутньому ми б почали залучати тестерів ще до релізу, щоб зібрати фідбек і уникнути таких ітерацій після запуску.
Що не працювало
- Геолокація не оновлювалась після першого запуску.
- Дублікати івентів — люди не бачили, що схожий уже створено.
- Firebase-ліміти — частина пушів просто не надходила.
Що спрацювало
- Локальна стрічка — не вантажимо користувача шумом з інших міст.
- Push-нагадування — приходять у ключовий момент, підвищують attendance.
- Пошук подій — користувачі це відзначають у фідбеку.
- Кешування — пришвидшує UX.
- Рекомендації — алгоритм, який формує персоналізовані рекомендації ігор на основі раніше зіграних ігор користувача, типів спорту, якими він цікавиться, ігор, у які грають його друзі, а також рекламованих ігор. Алгоритм враховує географічну близькість (у радіусі 50 км), відповідність спортивних інтересів та рівня підготовки, соціальні зв’язки (участь друзів або знайомих організаторів), популярність гри (кількість учасників і черга) та час до початку гри (пріоритет для ігор, що відбудуться протягом тижня). Рекомендації сортуються за бальною системою, де вищий бал відповідає більш релевантним іграм.
Метрики
На момент написання статті:
● 100+ користувачів (органічний трафік).
●
● 30+ видів спорту.
● Доступність: глобально (міста не обмежено).
● DAU:
● Retention Day 1: ~34%.
● Conversion to event create після реєстрації: 23%.
Очікування та оцінка результатів
На старті ми ставили амбітну мету досягти 500 користувачів за перші три місяці після релізу (тобто до серпня 2025 року) та DAU на рівні
Проте ми задоволені Retention Day 1 (~34%), оскільки це вище середнього для нових мобільних застосунків
Кількість подій
Всі метрики відстежуємо через Grafana + Google Analytics + Expo Insights.
Просування
На старті все органічно:
- соціальні мережі — створення та просування Instagram та Facebook-сторінок;
- знайомі організатори — пушили їм застосунок, збирали фідбек, залучали до організації івентів у нашій апці;
- ASO;
- опитування користувачів у чатах — завчасно зібрали свою базу для обробки шляхом пошуку за ключовими словами, тим самим рекомендаціям друзів та рісьорчу з використанням таких інструментів як Telemetr.io, Ahrefs, Similar Web, гугл видачі.
Плануємо:
- побудову партнерств із власниками спортивних клубів і майданчиків.
- співпрацю з мікро-інфлюенсерами — наразі вже створено декілька відео, одне з яких тестуємо на рекламі.
- інтеграції в локальні спільноти.
Що зробили б інакше
- Раннє тестування на Android — зекономило б багато часу.
- Просування до релізу — втратили перший імпульс.
- QA з першого спринту.
- Прототипування бібліотек — уникнули б конфліктів.
- Підготовка Apple-документів заздалегідь.
Плани на майбутнє
- Монетизація: внутрішня валюта, платне просування, підписка без реклами
- Фічі: темна тема, ачивки.
- Ринки: Європа, Америка.
- Партнерства: локальні спортклуби, волонтери, амбасадори.
Висновки
Sportouch — це наш перший публічний застосунок. Ми не перші, хто зіткнувся з проблемою «немає з ким пограти», але ми перші, хто вирішив це технологічно — просто, швидко, по-людськи.
Розробка мобільного застосунку — це не тільки код. Це адаптація під Android, факапи з API, боротьба з Apple, і (раптом!) UX-перемоги.
Сподіваємося, наш досвід буде корисний тим, хто тільки починає.
Якщо вам цікаві технічні деталі (архітектура, інтеграції, кешування) — пишіть у коментарях, поділимось більше. Якщо хочете спробувати Sportouch — шукайте в App Store або Google Play.
37 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів