Как стать автором
Поиск
Написать публикацию
Обновить

Проверенный стек технологий для быстрого создания Web SaaS в 2025 году

Уровень сложностиПростой
Время на прочтение7 мин
Количество просмотров1.3K

Привет, Хабр! Меня зовут Данил Чернышев, я разрабатываю альтернативу Agile и хочу поделиться своим проверенным стеком библиотек и технологий для скоростной разработки Web SaaS в 2025 году. Прошу профессиональное сообщество в комментариях поделиться своими рецептами для создания качественных программных продуктов.

Архитектура и требования к продукту

Мой сервис представляет собой систему управления продуктами. С точки зрения характера движения данных, он сходен с классическими системами управления проектами: Jira, ClickUp, Asana, Basecamp и так далее. Они представляют собой low-read и low-write сервисы, фактически коллекции документов, продуктовых спецификаций. Для них, в первую очередь, важна скорость доступа к данным – насколько быстро открывается тикет по клику с канбан-доски. По сравнению с условной социальной сетью, это не высоконагруженный тип продуктов. Вторым критическим фактором является эффективность и скорость поиска, что довело, к примеру, Atlassian до создания собственного языка для поиска, Jira Query Language (JQL). Особенности концепции моего продукта, в том числе отсутствие канбан-доски, позволили мне не внедрять поиск вовсе, по крайней мере, на начальных стадиях развития.

Очень многие небольшие стартапы в SaaS сфере выбирают Typescript / NodeJS / React экосистему в силу ее простоты и широкого ассортимента разнообразных библиотек. Мой проект не стал исключением и сейчас он представляет собой Typescript + React + Redux Toolkit фронтенд приложение, NodeJS + ExpressJS бекэнд приложение с MongoDB инстансом, сервер аутентификации Supertokens с базой Postres. Каждое приложение или база завернута в Docker контейнер и разворачивается одним bash скриптом, который устанавливает и настраивает Docker, скачивает и запускает образы, устанавливает реверс прокси Nginx и SSL сертификаты с помощью Let’s Encrypt. Инстансы приложения развернуты на Яндекс.Облаке и зарубежных сервисах для максимальной скорости для конечного пользователя по всему миру. Но так было не всегда, и на этом пути я сделал ряд ошибок. Начнем рассказ по порядку, с фронтенда.

Фронтенд

React начал набирать популярность в 2017 году, и уже в 2018 году у меня появилась возможность получить коммерческий опыт работы с ним. С тех пор кроме React у меня был небольшой опыт работы с Angular, AureliaJS (мало кто знаком с этим чудом природы) и VueJS. Ничего проще, чем React с его JSX, с тех пор не изобрели. Несмотря на то, что последние годы команда разработки React пытается флиртовать с серверными компонентами, переизобретая PHP, React остается единственным рабочим вариантом для быстрой разработки фронтенд приложений в 2025 году в силу огромной экосистемы библиотек и простоты.

State management – более щекотливая тема. Я работаю с Redux с 2018 года, и принципы единого источника правды (single source of truth) с однонаправленным движением информации (unidirectional flow, Flux pattern) служили мне верой и правдой много лет. Какое-то время назад Redux эволюционировал в Redux Toolkit c концептами слайсов и API - файлов, фактически вырвав почву из-под ног всех критиков Redux о том, что надо писать много бойлерплейта. В 2025 году Redux Toolkit не имеет никакого бойлерплейта и прост, как пять копеек. Кроме этого, мейнтейнеры Redux создали Redux Toolkit Query, интегрированную в Redux, которая берет на себя все аспекты HTTP запросов, их статуса и обработки ошибок. RTK Query покрывает 95 процентов всех юзкейсов моего фронтенд приложения. Библиотека основана на redux thunk, библиотеке управления сайд-эффектами. Ее подход проще, чем Redux Sagas, но в моем приложении нет сложной оркестрации API-запросов или race conditions, которые удобнее решать с помощью саг.

Справедливости ради хочу коснуться mobx, еще одной популярной библиотеки управлением состоянием. Главное отличие – большая гибкость, можно создавать бесконечное количество сторов с данными. У меня был небольшой опыт с mobx в 2020 году, и мне запомнилось только то, что в mobx есть пять взаимозаменяемых способов диспатчить action creator’ы. Зачем? Я так и не понял. Зачем несколько сторов, если достаточно одного? Тоже непонятно. Довод о том, что один стор Redux может стать слишком большим и влиять на производительность, несостоятелен – в 2019 году я складывал в Redux огромные geoJSON’ы для карт, и стор мог весить десятки мегабайт с нулевым влиянием на производительность. Итог – Redux Toolkit + RTK Query мой выбор в 2025 году.

Стили и компоненты. Самую первую версию MVP я начал строить с помощью Ant Design, китайской библиотеки компонентов. У них огромное множество различных компонентов на любой вкус, в том числе очень сложных. Однако приложение начало выглядеть как-то по-китайски, и я решил сделать что-то сам на базе Tailwind. Делать что-то сам я быстро устал, и нашел популярную коллекцию компонентов Shadcn, которую использует сейчас каждый второй западный стартап. Получилось незамысловато, но неплохо, темная тема заработала практически из коробки. Для сайта проекта я использовал платные компоненты, которые купил на shadcnblocks.

Что касается архитектуры самого приложения, у меня есть выработанная годами структура файлов, компонентов, интерфейсов и доменов, основанная на древовидном принципе, которая позволяет коду оставаться читаемым, расширяемым и понятным даже людям с минимальными знаниями фронтенда. Возможно, это будет темой другой статьи.

Бекэнд

Вдохновившись видео на ютубе от ребят из YCombinator, я хотел запустить все очень быстро, используя сторонние сервисы для решения любых задач, которые можно было решить на стороне. Само бэкенд-приложение представляло собой управляемое (managed) NodeJS + ExpressJS приложение на DigitalOcean App Platform, и все. Для аутентификации я использовал популярный сервис Auth0, а для сторонней базы данных – SaaS сервис MongoDB Atlas, который мне стоил денег.

Я осознал свою ошибку, когда начал общаться с пользователями и делать демо. Управление продуктами и проектами – это критически важный элемент процесса разработки, и людям очень важно знать, что их данные в безопасности и они их контролируют полностью. Когда разработчик-одиночка предлагает вам перенести важные процессы компании на его непонятные сервера, причем неизвестно, что с ним случится завтра – это не внушает доверия. Я понял, что фокусом развития должна быть коробочная self-hosted версия, которую можно быстро развернуть на любом сервере с помощью одного скрипта, подключить домен и наслаждаться высокой скоростью работы.

С точки зрения архитектуры мой бекэнд – это куча простых CRUD эндпоинтов, организованных тематически по доменам. Никакой оркестрации, никакой Кафки или состояния, просто перекладывание джейсонов в MongoDB туда и обратно с небольшой трансформацией с фокусом на то, чтобы максимально снизить количество запросов от клиента. Еще одним плюсом NodeJS + ExpressJS является то, что валидацию входящих запросов можно делать с помощью библиотеки Yup, которую я использую и на валидации форм на фронтенде.

Как я говорил выше, для этого приложения очень важна скорость перекладывания джейсонов, что отражается на скорости загрузки тикетов на фронтенде. Я анализировал скорость зарубежных и российских конкурентов по количеству и скорости выполнения запросов, и к моему удивлению, не все они очень старались сделать свои приложения очень быстрыми или сократить количество необходимых запросов. Некоторые российские системы управления проектами грузили тикеты по 300-400 миллисекунд. Здесь я хочу отметить российский проект YouGile – их приложение грузит тикет за 50-60 миллисекунд. В моем случае сочетание отсутствия массированной трансформации джейсонов, использование MongoDB и деплой приложения в московское Яндекс.Облако позволило довести скорость загрузки тикета до 30-40 миллисекунд при запросах из Москвы. С учетом фокуса на self-hosted версию, каждый пользователь может развернуть инстанс моего сервиса в наиболее близком к себе регионе и получить очень большую скорость работы. UX очень важен.

Однако переделка приложения с зависимостей от MongoDB Atlas и Auth0 заняла у меня пару месяцев (я работаю над проектом после основной работы по вечерам и выходным), и если перевести базу данных с MongoDB Atlas на локальный Docker инстанс той же базы было делом одного вечера, то с аутентификацией пришлось попотеть.

Аутентификация

Давным давно я делал собственные iOS приложения на Swift с использованием Firebase, чтобы не писать для них отдельный бекенд. Firebase SDK включает в себя аутентификацию, поэтому я обратился в первую очередь к Supabase, open source версии Firebase. Я много прочитал о поддержке self-hosted в Supabase и пришел к выводу, что я не уверен в надежности их решения. Коробочная версия не выглядела как приоритет для Supabase и она не получала такого внимания, как SaaS версия. Я начал искать решение, которое бы 1) было ориентировано на деплой на своем сервере 2) поддерживало NodeJS как first class citizen. Так я наткнулся на молодой стартап Supertokens, в который инвестировал YCombinator. Он представляет собой отдельное серверное приложение с Postgres базой. Главное бекенд-приложение общается с сервером Supertokens для JWT аутентификации, создания и изменения пользователей. Возможно, я столкнусь с проблемами, когда дойду до SSO аутентификации, но на текущем этапе все это работает как часы.

Фронтенд часть аутентификации реализована через собственный SDK, ориентирована на React и максимально проста, еще проще, чем Auth0.

Деплой

Во всех стартапах, где я работал, были отдельные админы, а затем девопсы, которые отвечали за CI/CD, поэтому у меня не было большого опыта написания конфигураций для Docker или Kubernetes с нуля. Во второй фазе моего проекта, когда я переносил все из сторонних сервисов в единый деплоймент, мне пришлось выучить оба, и в этом мне огромную помощь оказал Cursor с моделью Claude Sonnet 3.7. Я достаточно скептически отношусь к вайб-кодингу и в основном использую курсор для весьма умного автокомплита, но в деле написания yaml’ов для Docker и Helm шаблонов для Kubernetes Cursor сэкономил мне многие десятки часов времени чтения документации. В итоге с почти нулевого уровня знаний я смог поднять рабочий managed Kubernetes кластер на DigitalOcean за несколько дней, и весь процесс требовал только одного запуска Helm скрипта.

Проблемы начались, когда я увидел, что managed Kubernetes на Яндекс.Облаке стоит в два раза дороже, чем на DigitalOcean. Когда же я попытался завести кластер с помощью своего Helm скрипта на обычной VM, ничего не получилось. Я подумал и решил, что в моем случае Kubernetes особо и не нужен. Структура проекта простая, всего пять Docker образов и реверс-прокси, и zero downtime мне не нужен.

После этого вместе с Сursor я очень быстро создал интерактивный bash скрипт, который устанавливает на любую виртуальную машину Docker, скачивает нужные образы, заводит их, ставит реверс-прокси и SSL сертификаты. На зарубежных VM установка занимает 5 минут, на Яндекс.Облаке - 10 минут (там образы скачиваются с DockerHub почему-то в три раза медленнее).

С помощью этого скрипта я запустил инстансы сервиса во всех ключевых регионах мира, включая Россию, чтобы обеспечить максимальную скорость работы. Однако я открыто говорю пользователям о том, что им следует рассмотреть вариант с размещением на своих серверах, потому что это безопаснее и надежнее. Большинство сервисов управления проектами дает эту возможность только большим клиентам. Мой проект – всем.

Профессиональное сообщество Хабра разрабатывало все возможные типы приложений. Прошу Вас делиться проверенными вашим опытом технологическими стеками в комментариях.

Чтобы не пропустить новые публикации об архитектуре фронтенд приложений, качестве кода, продуктовых методологиях – подписывайтесь на мой аккаунт на Хабре. Чуть ниже для этого есть кнопка.

Теги:
Хабы:
Всего голосов 7: ↑4 и ↓3+2
Комментарии33

Публикации

Ближайшие события