Архитектура FoodTech-приложения на React Native: как собрать стабильный продукт и не утонуть в деталях
FoodTech-приложения очень требовательны с точки зрения архитектуры. Они объединяют динамические каталоги, заказы в реальном времени, карты, оплату, лояльность, отзывы и поддержку. При этом пользователь ждёт, что всё будет работать мгновенно, даже на старом телефоне и при плохом интернете.
Мы в dev.family разрабатываем мобильные продукты для фудтеха и e-commerce уже порядка 10 лет и собрали свой стек решений, который помогает запускать приложения быстро и стабильно. Ниже рассказываем, из чего состоит архитектура типового фудтех-приложения, какие технологии мы используем и какие ошибки чаще всего мешают масштабированию.
Зачем фудтеху нужна продуманная архитектура
У фудтеха есть несколько особенностей, которые значительно «усложняют» и удорожают разработку:
- динамичность данных: меню, акции, статусы заказов меняются каждую минуту;
- высокие пиковые нагрузки: десятки тысяч пользователей в вечерние часы и праздничные дни;
- чувствительность к UX: задержка в одну секунду может стоить потери заказа.
Без чёткой архитектуры приложение быстро начинает «сыпаться»: данные рассинхронизируются, интерфейс зависает, а новые функции внедрять становится всё сложнее. Поэтому продуманный стек решает не только инженерные, но и бизнес-задачи – ускоряет релизы, снижает количество багов и упрощает масштабирование.

Онлайн-заказы без сбоев: как ресторанам и ритейлу обеспечить стабильность и рост
Читать статьюОсновные модули фудтех-приложения и как мы их строим
Корзина
Для реализации корзины в приложении мы обычно используем Zustand или Redux Toolkit. Для хранения данных между сессиями – MMKV (она быстрее AsyncStorage и не блокирует UI). Серверная синхронизация реализуется через WebSocket или фоновые запросы, при потере соединения данные временно хранятся локально и догружаются позже.
Главная сложность – поддерживать консистентность между клиентом и сервером. Мы решаем это через строгую систему версионирования состояния и явные события (add/update/remove), которые проходят полную синхронизацию.
Также бывают проблемы с откликом, особенно на старых девайсах. Здесь важно оптимизировать интерфейс (FlashList для списков, мемоизация компонентов). Порой лучше отказаться от сложных анимаций, и отдать приоритет быстрой реакции интерфейса на действия юзера.
Это приводило к проблемам при оформлении заказа. Версионирование корзины решило ее, клиент отправлял номер версии корзины вместе с каждым изменением, и сервер принимал его или отклонял, если версия устарела. В ответ сервер всегда возвращал актуальное состояние корзины.
Авторизация
Основной сценарий – вход по номеру телефона. Для этого есть готовые инструменты, такие как маска номера (react-native-mask-input), автоопределение страны, хелперы для корректной обработки клавиатуры.
Если требуется защита от спама или автоматических регистраций, можно встроить капчу, так же есть готовые решения для интеграции Google reCAPTCHA и hCaptcha, например
Кроме того, можно легко подключить Google, Apple или Facebook авторизацию.
Для сети пивных магазинов «Пивточка» использовали номер телефона при регистрации, потому что у них старая программа лояльности была завязана именно на нем, а в наши задачи входило перевести пользователей из оффлайна в мобильное приложение. Только таким образом мы могли вычислить старых клиентов, у которых были пластиковые карточки.


В целом, если вы создаете приложение доставки то вам и так потребуется телефон для связи курьера с клиентом. Поэтому запрашивать его на начальном этапе – это не моветон. А дополнительный способ валидировать человека, подтвердить его реальные намерения относительно заказа.
Каталог
Для списков и карточек товаров хорошо работает react-native-flas-list - мощная альтернатива стандартным компонентам, не тормозит даже при сотнях позиций.
Изображения кешируются через react-native-fast-image, чтобы блюда открывались мгновенно и не мигали при пролистывании.
Сложности чаще всего возникают при загрузке большого числа изображений или сложных фильтров, без кеширования каталог фризит. Важно заранее продумать пагинацию, предзагрузку и отображение скелетонов при медленном интернете.


Прогрессивный рендер изображений с использованием blurhash
Читать статьюКарты
RN поддерживает все популярные карты: Google Maps, Apple Maps, Yandex, Mapbox. Через react-native-maps или @rnmapbox/maps можно использовать почти весь нативный функционал: маркеры, маршруты, зоны, геолокацию, геокодинг.
Для автоподстановки адреса по тексту - Google Places API или Yandex Geocoder. Для трекинга курьера обновления по WebSocket с плавным движением маркера.
У некоторых карт бывают проблемы с отображением кастомных пинов и кластеризацией. Без оптимизации такие элементы могут рендериться с задержкой или исчезать при масштабировании. Мы решаем это использованием оптимизированных изображений и принудительным контролем ререндера маркеров.
Также стоит внимательно работать с разрешениями на геолокацию и частотой обновлений, потому что слишком частые запросы координат могут просаживать производительность.
Решили это так:
- снизили частоту отправки координат до 2-3 секунд
- добавили интерполяцию движения маркера на клиенте
- включили дебаунс обновлений, чтобы не спамить карту при малых изменениях координат.
Программа лояльности
Программы лояльности обычно связана с интеграция с Apple Wallet и Google Wallet.
В React Native для этого используется библиотека react-native-wallet-manager, которая позволяет добавлять бонусные карты и купоны прямо из приложения.
В проекте «Джон Дори», где мы разработали приложение с программой лояльности, мы предоставили возможность пользователям добавлять карту в Wallet. С одной стороны это сыграло на руку с точки зрения лояльности клиентов – забота об их удобстве. А с другой – мы настроили возможность отправлять пуши, когда клиент оказывался в непосредственной близости с точками продаж. В карту лояльности зашивали локации, их координаты, и, когда покупатели проходили рядом, – на экране блокировки iPhone появлялись уведомления.


Такую фичу можно реализовать и с помощью bluetooth-маячков.
Отзывы
Модуль отзывов обычно включает текст, фото и рейтинг. Всё это реализуется на стандартных RN-компонентах без необходимости нативной логики.
Для работы с фото удобно использовать react-native-image-picker или expo-image-picker, для обрезки и сжатия react-native-image-crop-picker или react-native-compressor.
Основные риски связаны с работой с медиаконтентом и загрузкой изображений на сервер. На слабых устройствах важно не держать фото в оперативной памяти, это может привести к сбоям. Проблему можно минимизировать за счёт предварительного сжатия файлов и ограничения количества загружаемых изображений.
Еще стоит предусмотреть обработку отзывов в офлайн-режиме, данные лучше временно сохранять локально и отправлять их автоматически при восстановлении подключения к сети.


Все отзывы попадали в очередь на отправку. Когда сеть появлялась (отслеживалось через @react-native-community/netinfo), отзывы отправлялись по одному, после успешной отправки удалялись из очереди. В интерфейсе такие отзывы помечались как «Ожидает отправки». При тестах была проблема, что в некоторых сценариях очередь могла стать очень большой и экран тормозил. Решили за счет отображения только первых 10, остальные подгружались при прокрутке.
Если сервер падал или сеть пропадала,тогда пытались отправлять повторно с растущим интервалом (от 10 секунд до 1 минуты). В итоге пользователь мог оставлять отзыв всегда, даже офлайн, и ничего не терял.
Поддержка пользователей
Есть два пути:
- Свой чат. Полный контроль над логикой и данными. Реализуется на WebSocket или через бэкенд API. UI делаем на обычных RN-компонентах. Можно добавить статусы сообщений, вложения, push-уведомления.
- Готовое решение. Если важна скорость, проще использовать SDK вроде stream-chat-react-native, Sendbird или Firebase. Они закрывают 90% типовых задач.
В собственных чатах основная проблема это производительность при большом количестве сообщений и медиафайлов. В готовых SDK – ограничения по кастомизации и платные тарифы. Мы обычно выбираем подход исходя из нагрузки и бюджета проекта.
Но, если ТЗ предполагает кстомные элементы, например, возможность оформить заказ прямо из чата, оплатить бронирование по нажатию на кнопку или отобразить динамические карточки блюд/товаров, – правильнее сделать свой чат. Это позволяет полностью контролировать логику и не подстраиваться под ограничения SDK.
Пуш-уведомления
Для iOS и Android используются нативные сервисы: Firebase Cloud Messaging (FCM) и Apple Push Notification Service (APNs). В RN их удобно подключать через библиотеки @react-native-firebase/messaging или notifee. Они поддерживают обработку уведомлений в фоне, кастомные иконки, действия по клику и deep-links.
Если нужно централизованное управление кампаниями, интегрируются внешние платформы вроде OneSigma, Braze или Firebase Cloud Messaging Console
Маркетологи получили возможность самостоятельно запускать кампании и тестировать гипотезы, не привлекая команду разработки. В итоге цикл подготовки акций сократился с нескольких часов до нескольких минут.
AI-функции
Библиотека react-native-ai позволяет запускать модели ИИ прямо на устройстве или с минимальной задержкой, используя встроенные или лёгкие модели, что снижает зависимость от облака и улучшает отзывчивость.
Как это можно в фудтех-приложениях:
- Перевод отзывов: если пользователь оставил отзыв не на основном языке приложения, модель может на устройстве перевести его текст и показать перевод без дополнительного сетевого запроса.
- Умный поиск: библиотека поддерживает векторы (embeddings) и семантический поиск, можно искать блюда не только по точному слову, но по смыслу. Также можно оживить поиск и сделать его в формате чата, как вашего личного персонального помощника в приложении.
Важно учитывать, что локальные модели и обработка на устройстве требуют ресурсов, значит на слабых телефонах возможны задержки. Если используется облачная модель, нужно предусмотреть fallback-логику на случай отсутствия сети. При передаче данных на сервер следует соблюдать требования GDPR и локальные законы, особенно если обрабатываются отзывы с личной информацией.

Как настроить баннер cookie-согласия по требованиям GDPR, Google Consent Mode и законодательства разных стран
Читать статьюЭто напрямую отражается на удержании и конверсии: пользователям проще ориентироваться в меню, и они быстрее находят то, что им подходит. По сути, AI-поиск выполняет роль персонального помощника внутри приложения, что повышает доверие и лояльность к сервису.
Если вы не знаете, залетит ли такая опция для ваших пользователей, всегда можно попробовать с помощью лайтовых ассистентов, например, в WhatsApp. Мы сделали такого во время осеннего хакатона в компании. Им можно свободно воспользоваться без привлечения разработчиков. Вот тут можно почитать подробнее.

Типовые ошибки, которые влияют на масштабирование проекта и опыт пользователя
Самая распространенная история – проект, который на старте пользовался коробочным решением. Потом начал расти и понял, что коробка «мала» и на одних «костылях» далеко не уедешь. Некст степ – кастомная разработка. И тут надо принять, что эти расходы неминуемы, если речь о масштабировании.
Но есть и другой кейс. На старте проектом занимались специалисты без опыта в фудтехе. Они не знали о «подводных камнях», которые часто остаются незаметными на этапе MVP, но начинают болеть, когда продукт растёт. Они приходят за доработками. И так может случиться, что проще написать проект заново, чем реанимировать утопающего.
Мы собрали ключевые ошибки, которые регулярно встречались нам на пути и делимся ими с вами.
1. Отсутствие версионирования состояния
Когда разные устройства отправляют обновления корзины или заказа одновременно, сервер нередко принимает устаревшие данные. Так появляются «призрачные блюда», неверные суммы и ошибки при оплате. Без версионирования состояние клиента и сервера постоянно расходится, и каждая новая фича начинает работать нестабильно.
⛔️ Почему это критично
Рассинхрон – один из главных источников потерь заказов, особенно при высокой нагрузке.
Что может случиться при пиковых нагрузках в заведениях, читайте в нашей статье.
2. Несогласованный набор библиотек
Частая проблема – когда разработчики в одном проекте выбирают разные библиотеки для решения одной и той же задачи, не придерживаясь единой стратегии. В итоге:
- логика дублируется в разных местах,
- вес приложения растёт,
- обновление зависимостей становится болезненным и опасным.
⛔️ Почему это критично
Через полгода такой проект почти невозможно поддерживать без риска поломать существующий функционал.
3. Нет кеширования изображений и данных
Каталог блюд или продуктовая лента – самые тяжёлые экраны, особенно в приложениях с большим ассортиментом. Если изображения грузятся без кеша и оптимизации, на слабых устройствах появляются:
- фризы,
- долгие рендеры,
- падения приложения.
⛔️ Почему это критично
Каждый лишний лаг в каталоге снижает конверсию в просмотр блюда и, как следствие, в заказ.

Как оптимизировать работу с картинками на сайте или в приложении?
Читать статью4. Преждевременная оптимизация
Иногда разработчики пытаются предусмотреть все заранее: закладывают универсальные абстракции, усложняют слой бизнес-логики, продумывают архитектуру «на 10 лет вперёд». Конечно, это делается с целью создать масштабируемый проект.
- Но на практике такие решения приводят к обратному эффекту:
- проект движется медленнее,
- разрабатывать маленькие фичи становится сложнее, чем должно быть,
- новых участников команды дольше онбордить в проект,
- архитектура становится менее гибкой, потому что каждая часть связана с другой.
⛔️ Почему это критично
В фудтехе это особенно опасно: рынок быстро меняется, а продукт должен оставаться пластичным. Гораздо выгоднее строить архитектуру эволюционно, адаптируя её под реальные задачи, а не под гипотетические сценарии, которые могут никогда не наступить.
5. Отсутствие оффлайн-логики
Пользователи часто оформляют заказы в пути: в метро, лифте, между точками Wi-Fi. Если приложение не умеет переживать временное отсутствие сети, и у вас нет продуманных сценариев:
- корзина может «сброситься»,
- отзыв не отправится,
- заказ не оформится.
⛔️ Почему это критично
Любая из этих ошибок – не просто потеря клиента, а удар по репутации. Думаем, вы и сами негодовали, когда полностью собранная корзина оказывалась пустой. Или вы думали, что заказ уже скоро приедет, а на самом деле – он даже не был сформирован.

7 уроков для тех, кто хочет создать SaaS-продукт для ресторанов: опыт Foodclick
Читать статью6. Игнорирование лимитов и поведения карт
Google Maps, Yandex и Mapbox работают по-разному. У них отличаются:
- скорость рендера,
- качество кластеризации,
- ограничения по кастомизации.
Без понимания этих различий появляются дергания маркеров, зависания карты и повышенный расход батареи.
⛔️ Почему это критично
Трекинг курьера – ключевая точка опыта. Если карта лагает, падает доверие ко всему сервису.
О том, как это можно классно реализовать, читайте в нашем кейсе Sizl. Приложение для курьеров.
Как мы выстраиваем архитектуру в dev.family
1. Модульная архитектура
Каждый функциональный блок (корзина, каталог, отзывы, карта, чат) живёт отдельно.У него есть:
- свои данные,
- свои зависимости,
- свои интеграционные точки.
🔑 Что это даёт продукту
Можно менять один модуль, не задевая остальные. Например, заменить чат на SDK или переписать каталог под новые требования.
2. Понятная интеграция для каждого модуля
Заранее определяем, как модуль будет общаться с внешним миром:
- через API,
- через SDK,
- через WebSocket,
- через локальное хранилище.
🔑 Что это даёт продукту
Предсказуемость поведения и лёгкость масштабирования. Любой разработчик может быстро понять, где и как живут данные.
3. Максимально простая бизнес-логика
Интерфейс может меняться часто: акции, спецпредложения, новый дизайн. Но бизнес-логика (например, работа корзины или расчёт скидок) должна оставаться неизменной и независимой от UI.
🔑 Что это даёт продукту
Гибкость в редизайнах и A/B-тестах, а также более стабильное поведение приложения.
4. Offline-first решение
Каждый модуль продумываем в двух состояниях:
- онлайн — работает через API/WebSocket,
- офлайн — сохраняет данные локально, ставит их в очередь, отправляет при появлении сети.
🔑 Что это даёт продукту
Заказы, отзывы и другие операции не теряются.
5. Жизненный цикл данных
Мы заранее определяем:
- что хранится локально,
- что обновляется при каждом входе,
- что кешируется,
- что подгружается по запросу.
Используем MMKV, FlashList, FastImage, локальные очереди и фоновые синхронизации.
🔑 Что это даёт продукту
Приложение работает быстро, а поведение данных предсказуемо.
6. Место для будущих AI-функций
Мы уже видим, что AI-модули становятся стандартом в фудтехе: персональные рекомендации, семантический поиск, перевод отзывов, чат-помощник. Но на старте проекта они однозначно не нужны. Тем не менее мы обсуждаем с клиентом рост и развитие, поэтому оставляем пространство в архитектуре, чтобы эти функции легко было встроить.
🔑 Что это даёт продукту
Приложение можно развивать без болезненных переделок и технического долга.
7. Сильный упор на производительность UX
Мы оптимизируем:
- загрузку изображений,
- рендер списков,
- анимации,
- карту.
Используем мемоизацию, дебаунсы, кеширование, lazy-загрузку, оптимизированные компоненты.
🔑 Что это даёт продукту
Плавный интерфейс → больше действий → выше конверсия в заказ → выше LTV.
8. Набор проверенных инженерных шаблонов
Мы многократно переиспользуем штуки, которые точно работают:
- паттерны синхронизации корзины,
- паттерны работы с отзывами,
- шаблоны для каталогов,
- готовые модули пушей,
- готовые схемы WebSocket.
🔑 Что это даёт продукту
Запуск быстрее (значит, затраты на разработку ниже), меньше багов, стабильная основа для роста.
Что получает продуктовая команда
- Прозрачную, предсказуемую структуру.
- Возможность быстро добавлять новые функции (AI-поиск, рефералка и др.).
- Сокращение багов на проде за счёт единых паттернов.
- Ускоренный релиз за счёт переиспользуемых шаблонов dev.family.

Заключение
Хорошее фудтех-приложение начинается не с дизайна, а с архитектуры. React Native позволяет запускать сервисы быстро, но реальную устойчивость обеспечивают только продуманные модули, корректная работа с состоянием, кеширование, оффлайн-логика и управляемая синхронизация.
В dev.family мы выстроили архитектурный подход, который сочетает инженерную строгость, стабильность и гибкость под бизнес-цели. Такой фундамент делает продукт предсказуемым в поддержке, быстрым в развитии и понятным для всей команды.
Если вы планируете запуск нового приложения или хотите защититься от технического долга в текущем проекте – мы можем помочь разобраться, какие архитектурные решения подойдут именно вашему продукту.

