Когда речь идет о веб-разработке, а именно — о разработке форм, можно встретить множество мнений о том, «на чем» лучше делать проект. Очень часто React и Angular Framework рассматриваются как альтернативы друг другу. При этом выбор фреймворка — критически важный этап, который определяет дальнейшую разработку и особенности развития технологического стека компании.
В этой статье я хочу рассмотреть плюсы и минусы каждого из подходов и предлагаю подискутировать о том, каким должен быть «идеальный» фреймворк для разработки веб-интерфейсов, который поможет повысить скорость разработки проектов, сохранить или увеличить качество кода при этом сэкономить финансы предприятия.

Привет, Хабр! Меня зовут Сергей Лапин, я — ведущий разработчик в Cloud X. И чтобы подойти к теме веб-разработки, начну немного издалека. Не смотря на широкий спектр моих увлечений в области ПО и аппаратного обеспечения, основной вектор направления моей профессиональной деятельности — это web разработка во всех возможных ее смыслах и ипостасях. И я с уверенностью могу сказать, перефразируя старую русскую пословицу: «Сколько веб не программируй, формы делать все равно придется».
Моя практика разработки форм начиналась в банках и финансовых организациях. Так уж исторически сложилось, что в подавляющем большинстве случаев в финансовом секторе клиентская часть сервисов разрабатывается с использованием популярного фреймворка Angular. Давайте разберемся почему же это так. Для этого предлагаю обратить внимание на сильные стороны Angular Framework.

Модульная архитектура, которая позволяет эффективно управлять кодовой базой и масштабировать приложение;
Двусторонняя привязка данных, позволяющая автоматически синхронизировать данные между моделью и представлением;
Реализация паттерна MVC, которая делает возможным отделение бизнес-логики приложений от UI слоя;
Широкий спектр API включающий в себя богатый набор функций, начиная от управления событиями CSS анимации, заканчивая обработкой и контролем HTTP траффика.
Но не смотря на все очевидные преимущества, у Angular есть и существенные недостатки:
Высокий порог входа. Для работы с Angular требуется глубокое изучение всех библиотек, входящих в фреймворк и высокой степени профессиональной подготовки, желательно уровня senior;
Увеличение стоимости разработки. Нехватка специалистов на рынке в совокупности с квалификационными требованиями повышают стоимость специалиста, также повышается нагрузка на HR персонал при поиске и закрытии позиций.
А что насчет React?

В прикладных сферах web-разработки сейчас безусловно доминирует библиотека React. Причины популярности этой библиотеки кроются в ее преимуществах:
Гибкость: Нет привязки к архитектуре, единственное требование – оформление UI элементов в виде отдельных компонентов;
Поддержка популярных UI систем. Ant Design, Material UI, Radix UI, Chakra UI и прочие;
Низкий порог входа. Для успешного старта достаточно уровня подготовки уровня продвинутого junior;
Сниженный уровень затрат на разработку. Благодаря невысокому порогу входа рынок насыщен специалистами, что при правильном подходе позволяет гибко управлять затратами.
С сильными сторонами определились, теперь перейдем к недостаткам (куда ж без них?):
Речь идет только про UI-слой. Библиотека решает задачи только организации графического интерфейса;
Односторонняя привязка данных. Изменения UI компонентов в React не отражается на модели;
Высокий риск издержек. Исходя из того, что React не реализует комплексных архитектурных решений, есть высокий риск ошибки с выбором исходной архитектуры приложения, что может повлечь за собой рост технического долга с неизбежными затратами на его устранение.
Как бы это странно не звучало, но реализация только UI слоя является одновременно как сильной, так слабой стороной библиотеки React. В случае с библиотекой React мы имеем полную свободу выбора, создавать ли свои собственные библиотеки UI компонентов (мы в компании пошли по этому пути) или использовать готовые компоненты с возможностью гибкой кастомизации.
Что там с кадрами?
С качественными показателями разобрались, но сегодня нельзя планировать проект без учета популярности фреймворка среди программистов и доступности специалистов. Поэтому давайте посмотрим на количественные характеристики.
React |
Angular |
|
Популярность (Github Stars, %) |
220 000 |
95 000 |
Количество открытых вакансий (по данным hh.ru) |
120 000 |
50 000 |
Зарплата (Россия/СНГ, Senior) |
350 000 |
380 000 |
Насыщенность рынка (% на 1000 соискателей) |
75 |
25 |
Данные из открытых источников, цифры актуальны на конец 2025 года.
Чтобы сравнить показатели, лучше всего нормализовать значения в пределах 100% и построить диаграмму. Что же, если прагматично рассматривать ситуацию, React выигрывает по всем показателям.

Проект мечты
А теперь давайте пофантазируем и попробуем собрать себе «проект мечты», который обеспечит максимальное качество результата с минимальными затратами. Что же возьму себе я?! От React, в первую очередь, я возьму гибкость, поддержку популярных UI систем, сниженный уровень затрат на разработку и низкий порог входа, а от Angular я бы хотел взять реализацию паттерна MVC, модульную архитектуру и конечно же широкий спектр API с двухсторонней привязкой данных.
Очень хорошо, когда наши желания совпадают с нашими возможностями, но это случается крайне редко. Но, как это часто бывает, в нашем вопросе можно вполне небольшими усилиями «дотянуть» реальность до нужного уровня.
Библиотека |
Ожидания |
Реальность (реализация) |
React |
Гибкость |
Выбрать готовый или разработать свою UI систему |
поддержку популярных UI систем | ||
Низкий порог входа |
Оставить как есть |
|
Сниженный уровень затрат на разработку | ||
Angular |
Реализация паттерна MVC |
Успешно заменяется на MVVM |
Широкий спектр API и двусторонняя привязка данных |
||
Модульная архитектура |
Реализуется следованием правилам структурирования React компонентов, заложенных разработчиками в совокупности с общими правилами организации MobX сторов. |
Таблица желаний и возможностей
Как показывает таблица, все желания выполняются практически стандартными средствами, но вы же успели заметить, что одна ячейка осталась пустая. Дело в том, что за реактивность модели данных в Angular отвечает библиотека RxJS. Но так исторически сложилось, что в React проектах за реактивность отвечает библиотека MobX. И связка React+MobX хорошо себя зарекомендовала, и две эти библиотеки уже много лет идут рука об руку и почти стали синонимами.
Вот об этом недостающем куске паззла, без которого наша идеальная картина мира имеет мало шансов сложиться, и пойдет речь в следующей статье. Я расскажу о том, как была создана библиотека, которая средствами MobX реализует структуру хранения данных, методы манипуляций данными и точки отслеживания изменений. И все это для того, чтобы удачными архитектурными решениями, заложенными в конкурирующий фреймворке, можно воспользоваться в любом React-проекте без существенных доработок.
Комментарии (3)

DmitryKazakov8
27.02.2026 11:35Будет интересно посмотреть, как у вас будут реализованы формы и сравнить. Я обычно беру такой подход (универсальный для React, Solid, Vue, просто движок реактивности разный под капотом - синтаксис полностью одинаковый).
const form = new FormConfig<{ inputs: { objectType: TypeInputSelectConfig; insuranceStartDate: TypeInputDateConfig; }; submit: TypeInputSubmitConfig; }>({ inputs: { objectType: { type: 'select', value: { name: '', value: '' }, options: [ { name: 'АЗС', value: 'gas' }, { name: 'Краны', value: 'crane' }, ], validators: { emptySelect: validators.emptySelect }, errors: [], placeholder: messages.placeholderObjectType, }, insuranceStartDate: { type: 'date', value: '', validators: { emptyString: validators.emptyString }, errors: [], placeholder: messages.placeholderInsuranceStartDate, }, }, submit: { type: 'submit', label: messages.submit, }, }); class VM implements ViewModel { constructor() { makeAutoObservable(this, undefined, { autoBind: true }); } form = form.copy(); result = ''; handleSubmit() { const { objectType, insuranceStartDate } = this.form.inputs; const someValueInvalid = !objectType.check() || !insuranceStartDate.check(); if (someValueInvalid) { console.log('prevent submit'); } this.result = JSON.stringify(this.form.inputs, null, 2); } } export function Example() { const { vm } = useStore(VM); return ( <> <Form formConfig={vm.form} onSubmit={vm.handleSubmit}> {({ inputs, submit }) => ( <> <div className={styles.inputsLine}> {inputs.objectType} {inputs.insuranceStartDate} </div> {submit} </> )} </Form> <pre className={styles.pre}>{vm.result}</pre> </> ); }form здесь - независимый реактивный объект, в терминологии Mobx - observable. Расширяемый, полностью типизированный, можно создавать копии или использовать 1 инстанс если нужна синхронизация, SSR из коробки (в том числе с уже выведенными в интерфейс ошибками).
Разметка - декларативная, сами компоненты инпутов просто маппятся по type из любой UI-библиотеки с простой интеграцией (по сути в onChange инпуты меняют соответствующий value).
Соответственно, работают любые реактивные паттерны - computed геттеры (если нужно собрать данные из нескольких полей и по-особому вывести), autorun / reaction если нужна логика взаимосвязанности (например - при изменении одного поля изменить значение в другом или отфильтровать options / перевести в disabled, а также для взаимодействия нескольких форм).
В целом, подходит для сложнейших форм и не натыкался на ограничения. Единственное, что не всем понравится - data-driven (отсутствие каких-либо onChange колбэков). Если надо отреагировать на установку фокуса в инпуте - будет
reaction(() => insuranceStartDate.isFocused, callback), а это часто сложнее воспринимается, чем onFocus, и требует dispose при анмаунте компонента. Но для использующих реактивные подходы - привычно.Будет интересно сравнить с вашим решением.
paramparab
Интересно, ждем продолжения