Один репозиторий, чтобы править всеми: как переиспользование кода экономит недели разработки

Время прочтения — 10 минут
Содержание
Рассказываем, как отказ от «универсального» продукта помогает запускать новые приложения за два дня.

Почему одно приложение больше не работает

Помните времена, когда одно приложение пыталось делать всё сразу? Регистрация – общая, интерфейс – переключается по ролям, логика — вроде бы универсальная. На старте развития того же Uber все так и было: один продукт и для пассажиров, и для водителей. Пока всё не стало слишком большим. Слишком сложным. Слишком тяжёлым. В итоге их разделили — на Uber и Uber Driver. Так же потом поступили Glovo, Bolt, DoorDash. И правильно сделали.
Когда ты пытаешься уместить в одно приложение и клиента, и курьера, и поддержку, и весь бэк-офис – это уже не продукт, а Франкенштейн. Он растёт, начинает сам с собой конфликтовать и в какой-то момент рискует обрушиться под собственным весом.
В этой статье расскажу, как мы с командой разделили процессы дарк-китчина Sizl на три отдельных продукта, чтобы быстрее раскатывать обновления и релизить новые фичи, благодаря модульной архитектуре и схожих компонентах кода.

Наш бэкграунд

К экосистемам мы пришли не сразу. Например, одном из наших проектов – сервисе по бронированию бьюти-услуг – одним приложением могли пользоваться как мастера, так и их клиенты. Интерфейс адаптировался под роль, всё было вроде бы логично. Но чем больше росла система, тем чаще мы сталкивались с проблемами. Бизнес-логика разрасталась, потому что сценариев становилось всё больше. Любое изменение в одном сегменте могло сломать другой.
Приложение по поиску мастеров красоты и организации их работы
Мы уверены, что автоматизировать можно все: будь то бизнес-процессы международной компании или поиск косметолога. Эта история как раз о том, как быстро создать полезный инструмент по поиску мастеров красоты и правильно организовать их работу.
Так мы отказались от попытки втиснуть всю экосистему в одно приложение. И обкатали подход уже на следующем крупном проекте в крипто-домене. Это была платформа лояльности, где пользователи получали бонусы, а бренды – аналитику по их действиям. Архитектура включала Shopify-интеграции, клиентский портал, мобильное приложение, Chrome-расширение и серверную часть. И все это – кастомное.
Понимая масштаб и потенциал роста проекта, мы сразу заложили основу для стабильной и масштабируемой архитектуры. Выбрали единый стек – TypeScript – и настроили общие конфигурации, линтеры и правила оформления кода. Вместо множества разрозненных репозиториев собрали централизованный монорепозиторий: с чёткой структурой, повторно используемыми модулями и единой логикой.
Это позволило упростить локальную разработку, ускорить сборку, снизить порог входа в проект для  новых участников и обеспечить контроль качества.
Этот опыт стал основой для нашей следующей экосистемы – уже в рамках проекта Sizl.
Sizl: как мы стали техническим партнером сети дарк китченов в Чикаго
История работы над приложением для быстрорастущей сети дарк китченов с доставкой еды и самовывозом, которая началась с ребилда и продолжилась разработкой нового функционала. Сразу после релиза продукт привлёк инвестиции, а сама компания продолжила активно расширять своё присутствие в Чикаго.

От ребилда к экосистеме

История с Sizl началась с задачи перезапустить уже существующее приложение для сети dark-kitchen в Чикаго – с доставкой еды, самовывозом и лояльной аудиторией. Первая версия была написана на Kotlin Multiplatform – крутой, но нишевой технологии. Со временем внутренняя техническая команда обновилась, и фаундерам Sizl стало понятно: с поддержкой, масштабированием и развитием продукта могут возникнуть сложности.
Мы начали проект задачей с ребилда приложения на React Native и добавления нового функционала. Продукт уже имел рабочую бизнес-логику, понятные сценарии и реальные данные. А для разработчиков это просто мечта – ничего не надо выдумывать, просто собери всё грамотно и начинай улучшать.

Один код — много сценариев

Идея перейти на монорепу пришла от нашего мобильного разработчика Ильи – именно он уже реализовывал подобное решение на TypeScript в проекте, о котором я рассказывал выше. Поэтому у него сразу сложилась картинка, как можно объединить отдельные компоненты кода в управляемую экосистему.
Для Sizl мы организовали архитектуру так, что каждый блок системы – например, авторизация – оформлен как самостоятельный модуль со своей логикой, интерфейсом, хуками и данными. Такие модули хранятся отдельно и не зависят друг от друга напрямую.
И если логика авторизации понадобится нам в другом продукте экосистемы, мы не копируем код и не делаем прямой импорт. А вместо этого подключаем его как внешнюю зависимость через, так называемую, инъекцию зависимости: нужный модуль передается в нужное место как параметр, без жёсткой связи с исходным кодом. Это упрощает масштабирование, снижает риск багов и позволяет переиспользовать один и тот же функционал в разных приложениях.
Поэтому когда позже клиент пришёл с запросом: «А давайте сделаем еще отдельное приложение для курьеров», – нам не пришлось начинать с нуля. Многие части логики уже были прописаны в проекте, и мы просто подключили монорепозиторий, чтобы не плодить сущности.
Sizl. Как мы выпустили приложение для курьеров за 2,5 недели
Для Sizl – сети дарк китченов из Чикаго – мы уже запустили основное клиентское приложение в апреле 2025 года. Тогда всего за 3 месяца команда провела полный ребилд существующей версии, добавила новые функции и помогла клиенту подготовить продукт для презентации инвесторам. Следующий шаг – приложение для курьеров. Его выпустили отдельно, чтобы разделить бизнес-логику и управление процессами

Как мы организовали пакеты и модули

Монорепозиторий мы разделили на две части:
  • packages – сюда вынесли общие модули: API, компоненты, утилиты (например, для работы со временем, форматирования, обработки данных);
  • apps – здесь находятся два отдельных фронта: одно приложение для клиентов, другое – для курьеров.
По факту это позволило нам быстро собрать новое приложение, просто подключив нужные модули, прописав логику и привязав API. А в клиентском приложении заменить только импорты и ничего не сломать.
Такой подход позволил нам сильно ускорить релиз: на приложение для курьеров у нас ушло около 2,5 недель. При этом сам монорепозиторий мы собрали за неделю. А на приложение для поддержки планируем потратить всего 2 дня – там суперпростой флоу, поэтому точно знаем, что уложимся в срок.
Если бы backend был написан на Node.js, мы бы тоже включили его в монорепозиторий: вынесли бы клиент в отдельный пакет и просто импортировали его, без необходимости каждый раз генерировать API-документацию. Это упростило бы связку фронта с сервером и ускорило разработку.

В чем сила монорепозитория

Монорепозиторий – не магия, а инженерное решение. Да, на старте оно требует времени и усилий. Но если вы не просто тестируете гипотезы с MVP, а планируете строить зрелую цифровую платформу, эти инвестиции быстро окупаются и приносят новые преимущества:
  • Мгновенная раскатка изменений. Нашли баг в логике обновления токена? Поправили, и оно работает во всех приложениях. Без копипаста и ручных правок.
  • Поддержка качества кода. Находим баг и фиксим его один раз, чтобы обновить везде.
  • Бесконечное развитие. Пока технология живая (а для React Native регулярно выходят новые библиотеки), мы можем улучшать, оптимизировать и масштабировать всю экосистему.
И самое главное – пользователь тоже чувствует эти эффекты. Интерфейс становится легче, путь – яснее, сценарии – логичнее. Для команды разработки всё так же прозрачно: архитектура разделена, но связана, зоны ответственности понятны, и можно наконец-то не бояться «просто поправить в одном месте».
Остались вопросы по монорепозиториям? Мы здесь, чтобы помочь!
Читайте также