arrow_back Назад в блог
person Дмитрий Болотов

Почему я выбрал Bun и Hono для бэкенда QuotyAI

#bun #hono #backend #typescript #ai-development
translate
Доступно на:
info Эта статья переведена с помощью ИИ

Я не хотел переписывать бэкенд.

Три месяца назад у меня был прекрасно работающий бэкенд на NestJS. Он обрабатывал все вебхуки Facebook. Подключался к базе данных. Правильно рассчитывал цены. Он работал. Вроде как.

Но каждый раз, когда я добавлял новый эндпоинт, я испытывал точно такое же чувство, какое испытываю, открывая 1000-страничную государственную форму. Я знал, что потребуется 30 минут шаблонного кода, прежде чем я смогу написать ту единственную строку, которая реально что-то делает.

Это та часть, где каждый технический блогер говорит «а потом я всё переписал на Rust!»

Я не переписывал всё на Rust. Я переписал всё на Bun и Hono. И это лучшее техническое решение, которое я принял на этом проекте.

«Лучший фреймворк — тот, который ты не замечаешь»


Матрица решений

У меня было три реальных варианта.

Претенденты:

  1. Оставить NestJS на Node.js
  2. Переписать на .NET 10
  3. Перейти на Hono/ElysiaJS на Bun

Критерии:

Эту часть большинство людей пропускают. Я не оптимизировал для «лучшей производительности» или «больше звезд на GitHub». Я оптимизировал ровно для четырёх вещей:

  • Я один человек. Фреймворк должен мне не мешать.
  • Full stack TypeScript. Никакого переключения между языками.
  • AI-агенты должны хорошо писать код для него.
  • Строгая типизация везде, избегать проблем во время выполнения.

Давайте дадим каждому честный шанс.


Вариант 1: Оставить NestJS

Это был вариант по умолчанию. У меня уже было 50 000 строк работающего кода. Я знал все причуды. Я мог просто продолжать.

Но были проблемы, которые не исчезали:

Время сборки: 20 секунд. Каждое изменение. Каждый раз, когда я сохранял файл, у меня было достаточно времени, чтобы сходить за кофе, выпить половину и вернуться до перезапуска сервера. Я тратил 3-4 часа в неделю просто ожидая сборки.

Ад ESM: Половина экосистемы теперь на ESM. Половина всё ещё на CommonJS. Каждый раз, когда я добавлял новый пакет, был 50/50 шанс, что он сработает.

Хочешь импортировать относительный файл? Нельзя написать import './auth.service'. Надо написать import './auth.service.js'. С расширением .js. Хотя реальный файл на диске — .ts.

Хочешь использовать алиасы для src? Удачи. Некоторые инструменты их уважают. Некоторые нет. Некоторые уважают их только наполовину. Я потратил 12 часов в прошлом месяце, отлаживая почему один конкретный пакет не импортируется правильно. Никто не должен думать о системах модулей в 2026 году.

Bun исправляет всё это. Просто пиши импорт. Оно работает. Без расширений. Без флагов. Без type: module в package.json. Без хаков __esModule. Оно просто работает.

Шаблонный код DTO: Для каждого эндпоинта, который я хотел написать, мне нужно было:

  • Интерфейс
  • DTO класс с 7 декораторами
  • Схема валидации
  • Отдельное определение OpenAPI
  • Трансформер

Всё это для эндпоинта, который буквально просто принимает два числа и возвращает цену. Это было безумие.


Вариант 2: Переписать на .NET 10

Позвольте быть предельно ясным: я .NET разработчик и я его люблю.

Если вы .NET разработчик, читающий это, я понимаю. Я полностью понимаю.

Одна стандартная система маршрутизации. Два JSON-парсера во всей экосистеме. Строгая типизация по умолчанию. Отличные инструменты. Предсказуемо. Никакой драмы. Если бы я работал в команде из 5+ разработчиков, если бы это был корпоративный продукт, если бы я планировал нанимать людей, .NET 10 был бы очевидным, правильным, ответственным выбором.

Есть ровно ноль технических аргументов против .NET для такого бэкенда. Он быстрее. Стабильнее. У него лучше стандартная библиотека. AOT-компиляция. Для 95% всех бэкенд-проектов, создаваемых сегодня, .NET — правильный выбор для меня.

Но я не создаю 95% бэкенд-проектов. Я создаю QuotyAI. И у меня есть одно крайне странное ограничение, которое почти ни у кого нет:

90% кода для этого проекта пишу не я. Его пишут AI-агенты.

И вот неудобная правда, которую никто не скажет: AI-агенты довольно плохо пишут хороший C#.

Они могут писать компилируемый C#. Они могут писать работающий C#. Но каждый раз, когда я просил Claude, GPT или GLM написать мне простой .NET эндпоинт, он возвращался со стилем enterprise 2019 года. Три интерфейса. Два абстрактных класса. Паттерн фабрика. И где-то на 12 уровней глубже те три строки кода, которые реально делали то, что мне нужно.

Я тратил 15 минут, удаляя весь мусор, чтобы добраться до реальной логики. Для независимого основателя, который пишет 10 эндпоинтов в день, это 2,5 часа в день, потраченных на удаление шаблонного кода, который AI добавил абсолютно без причины.

И есть вторая, ещё более важная причина, о которой почти никто не говорит:

Каждый важный AI-фреймворк первым делом выпускает TypeScript-версию.

LiveKit. LangChain. OpenAI SDK. Anthropic SDK. Deepgram. Все они получают новые функции в TS на 3-6 месяцев раньше, чем появятся в .NET. Все примеры на TS. Вся документация на TS. Все исправления багов выходят в TS первыми.

Когда LiveKit выпустил свой API для реалтайм голосового агента в прошлом месяце, TypeScript SDK был доступен в день выхода.

Для продукта, который живёт и умирает возможностью использовать новейшие AI-инструменты сразу, как только они выходят? Эта разница не тривиальна.

И давайте будем совершенно честны о другом: вы на 100% правы.

.NET лучше TypeScript для фоновых задач. Саг. Распределённых транзакций. Надёжных очередей. Всё это скучное, сложное, важное, что нужно большим корпоративным системам. TypeScript экосистема здесь всё ещё на 5-10 лет отстаёт. Спорить не о чем. Если вы банковскую систему строите, ERP, или что-то, что должно надёжно обрабатывать 10 миллионов фоновых задач в день.

Но я не это строю. Я строю AI-продукт, где 90% сложности — в API эндпоинтах и логике AI-агентов. Не так много фоновой обработки.

Для команд? Для enterprise? Используйте .NET. Это объективно лучший универсальный бэкенд-фреймворк. Для меня, прямо сейчас, создавая этот конкретный продукт в 2026? Это был неправильный выбор.

«AI не пишет корпоративные паттерны — он пишет шаблонный код. Ваш выбор фреймворка должен это учитывать.»


Вариант 3: Hono на Bun

Я следил за этим с момента выхода, но никогда не использовал. То же самое про Deno.

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

Я старомодный разработчик. Я люблю ООП. Я люблю внедрение зависимостей. Я люблю паттерны, которые работают 30 лет. Hono позволяет мне писать код, который выглядит как обычный код, не как какой-то академический эксперимент по функциональному программированию.

Потом я попробовал.

bun dev запускается за 800 мс. Не 8 секунд. Я сохраняю файл, и сервер перезапускается прежде, чем палец оторвётся от ctrl.

Никакой драмы с системой модулей. Всё просто импортируется. Никаких флагов __esModule. Никаких споров require() против import. Оно просто работает.

А Hono? Hono не делает магии. Он не делает внедрение зависимостей. У него нет документации на 400 страниц.

Он делает ровно три вещи:

  1. Маршрутизирует запросы
  2. Валидирует входные данные
  3. Генерирует схемы OpenAPI

И он делает всё это, не заставляя меня писать шаблонный код.


Глубокое погружение в реализацию

Самая большая победа была не в производительности. Это была генерация схем.

С NestJS я бы написал это:

@ApiProperty()
@IsNumber()
@Min(1)
@Max(365)
nights: number;

@ApiProperty()
@IsNumber()
@Min(0)
cleaningFee: number;

А потом мне всё равно пришлось бы писать Zod схему отдельно. И потом всё равно пришлось бы писать TypeScript интерфейс. Три источника правды. Всегда не синхронизированы.

С Hono и hono-openapi я пишу это один раз:

const CreateBusinessEntityFactsSchema = z.object({
  facts: z.array(z.object({
    content: z.string(),
    tags: z.nativeEnum(FactTagEnum).array()
  }))
});

Всё. Это полное определение.

Hono автоматически:

  • Валидирует все входящие запросы во время выполнения
  • Генерирует идеальную документацию OpenAPI с описаниями и примерами
  • Даёт мне полные типы TypeScript во время компиляции через z.infer<typeof Schema>
  • Возвращает правильные ошибки 400 с указанием exactly какое поле не так и почему

Хочешь удалить лишние поля из запросов? .strip(). Хочешь сделать что-то частичным? .partial(). Хочешь объединить две схемы? .and(). Всё нативно. Всё встроено.

Никаких декораторов. Никаких DTO классов. Никаких 7 отдельных декораторов на поле. Никакой магии. Просто один источник правды.

Вся переписка заняла 3 дня. Не 3 недели. 3 дня. Я удалил 2000 строк шаблонного кода, и приложение работало точно так же. Но теперь собирается за 2 секунды вместо 45.

Это не теоретически. Каждый эндпоинт в QuotyAI работает именно так. Файл маршрутов, который обра все извлечение фактов бизнеса, OCR, перевод и генерацию AI подсказок? Он длиной в 950 строк.

На NestJS тот же функционал был бы 3000+ строк, разбросанных по 12 разным файлам. Контроллеры. DTO. Провайдеры. Модули. Интерфейсы. Всё для абсолютно того же функционала.

Если бы мне пришлось делать это снова? Я бы сделал это на 2 месяца раньше. Я так много времени потратил, борясь с NestJS, когда мог просто создавать фичи.

Диаграмма сравнения шаблонного кода NestJS и определений схем Hono из одного источника

Цена входа

Это не пост «всем нужно использовать Bun и Hono». Это то, что работает для меня.

У каждого выбора есть компромиссы. Вот чем я жертвую:

  • Меньшая экосистема: Нет готовых пакетов для каждого крайнего случая. Я пишу код сам вместо отладки гигантских абстракций.
  • Меньше Stack Overflow: Когда что-то ломается, есть 3 ответа вместо 1000. Один из них обычно мой.
  • Нет защитных ограждений: Hono не останавливает вас от написания плохого кода. Он просто уходит с дороги.
  • Случайные баги: Вещи ломаются. Драйвер MongoDB имел утечку памяти на прошлой неделе. Исправили.

.NET стабильнее. Более зрелый. Лучше для команд. Если вам это нужно, используйте. Вы правы.

Блок-схема принятия решений о выборе бэкенд-фреймворков в 2026 году

Вердикт

Для меня, прямо сейчас, это идеальный стек.

Я могу написать эндпоинт, добавить валидацию, получить полные типы и иметь документацию OpenAPI за 2 минуты. Не за 20.

Claude, GPT и GLM прекрасно понимают Hono. Они пишут чистый, простой код без всего этого корпоративного мусора.

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

Этот стек не оптимизирован для 100 разработчиков. Он оптимизирован для одного разработчика, которому нужно двигаться очень быстро.

Именно это и нужно QuotyAI.

Мне не нужен фреймворк, который масштабируется до 100 инженеров. Мне нужен фреймворк, который позволяет одному инженеру масштабироваться до 1000 пользователей.

«Оптимизируйте под свои ограничения, а не под чужие лучшие практики.»

И прямо сейчас, Bun и Hono — лучшие инструменты для этой работы.


Часто задаваемые вопросы

Почему выбрать Bun и Hono вместо NestJS?
Bun устраняет проблемы с ESM-модулями и обеспечивает запуск за 800 мс, а Hono избавляет от шаблонного кода без ущерба для типобезопасности — критически важно для независимых основателей, которым нужно быстро двигаться.

Как производительность AI-агентов влияет на выбор фреймворка?
AI-агенты пишут на 30-50% меньше шаблонного кода для Hono по сравнению с .NET или NestJS, экономя 2,5+ часа ежедневно на удалении ненужных корпоративных паттернов.

Какие компромиссы при использовании Bun и Hono?
Меньшая экосистема, меньше ответов на Stack Overflow, нет защитных ограждений и случайные баги — но это приемлемые компромиссы для основателей, приоритетом которых является скорость.


Технические ссылки и источники:

Спасибо за чтение!
Читать другие статьи