Houdrik
Opinion
· 30 вересня 2025 р.· 8 min read

Без прив'язки до стеку не означає без замовчувань

Найпоширеніше хибне прочитання фрази «ми обираємо стек під проєкт» — нібито в нас немає думки ні про що. Вона є. Просто це підлога, а не стеля.

Cover · stack-agnostic-does-not-mean-no-defaults

Найпоширеніше хибне прочитання фрази «ми обираємо стек під проєкт» — нібито в нас немає думки ні про що. Це не так, і якби було так — користі від цього не було б ніякої. Насправді це означає інше: значення за замовчуванням існують, і вас треба нас із них переконати.

Звучить як дрібна різниця. Це не так. Це різниця між сеньйорською командою і пулом підрядників у футболці з написом «сеньйорська команда».

Замовчування — це те, до чого ми тягнемося, коли ніщо не каже тягнутися до іншого

Це повне визначення. Не «єдине, що ми вміємо». Не «те, що ми втиснемо у ваш проєкт незалежно від того, чи воно личить». Це відповідь, яку ми даємо, коли проєкт ще не дав нам причини відповісти інакше.

Студія без замовчувань — це студія, яка перепроводить кожен проєкт з нуля. Кожен старт перетворюється на двотижневу дискусію про реляційне сховище, у якій ніхто не дізнається нічого нового. Кожне рішення про кеш стає круглим столом. Кожна розмова про фронтенд починається з «а може, просто HTML?». Це не сеньйор. Це вічний джуніор, перевдягнений у відкритість розуму.

Сеньйорська інженерія — це протилежне. Це короткий перелік сильних замовчувань, застосованих без церемоній, і довгий перелік умов, за яких ми спокійно їх відкинемо. Знати обидва переліки — це і є сеньйорство команди. Запам’ятати один без іншого — це або жорсткість, або відсутність керма.

Тож ось короткий перелік за категоріями. Ми озвучимо його і на першому дзвінку — за час, менший, ніж ви витратили на цей абзац.

Реляційне сховище: Postgres, майже завжди

Postgres — це швейцарський ніж. Він не найкращий реляційний рушій у жодній окремо взятій речі — є колонкові сховища, які обходять його на аналітиці, вбудовані рушії, що виграють у простоті єдиного процесу, і документні сховища, які виграють у гнучкості без схеми. У чому Postgres найкращий — це бути добрим одразу в багатьох речах: ACID-транзакції, JSONB, повнотекстовий пошук, часткові індекси, LISTEN/NOTIFY, обгортки зовнішніх даних, зрілі розширення, і спільнота, яка вже бачила кожен режим відмови, що його ви ось-ось відкриєте для себе.

Для приблизно дев’яти з десяти проєктів, які ми беремо, цей набір виграє. Не обов’язково бути найкращим в одному, якщо ти правильний інструмент майже для всього, що проєкт викине на тебе в перші два роки.

Ми обрали б щось інше у конкретних випадках. Аналітичні навантаження з мільярдами рядків і агрегаціями лише на читання? DuckDB локально або колонкове сховище віддалено. Однооренда вбудована задача, де піднімати сервер — надмірно? SQLite, із задоволенням. Форма документа, яка справді не лягає на реляційну модель — нерегулярна, глибоко вкладена, зі схемою на читанні за своєю природою? Неохоче MongoDB, і ми наполягали б на серйозній розмові: ця нерегулярність справжня чи це просто недодумана модель.

Це справжні причини. «Я прочитав один пост у блозі» — ні.

Черга та кеш: Redis

Redis — це кеш за замовчуванням, коротка черга за замовчуванням, обмежувач частоти за замовчуванням, служба блокувань за замовчуванням, pub/sub за замовчуванням для невеликого розгалуження. Він швидкий, простий, має відомі режими відмови, і операційна поверхня достатньо мала, щоб один інженер міг тримати його на собі, не з’їдаючи весь свій тиждень.

Ми обрали б справжнього брокера — Kafka, NATS, іноді RabbitMQ, залежно від форми задачі, — коли в проєкті є потоки подій, яким потрібне довговічне перевідтворення, розгалуження в масштабі, на якому Redis pub/sub захлинеться, або жорсткі гарантії порядку між розділами. Це не більшість проєктів. Коли таки так — ми не вдаємо, що Redis вистачить; але й не вдаємо, що його замало, коли його достатньо.

Фронтенд: типізований компонентний фреймворк із серверним рендерингом як громадянином першого класу

Тут у нас теж є замовчування. Це фреймворк, який найшвидше окуповує себе на тому типі роботи, який ми зазвичай робимо: маркетингові поверхні, дашборди, внутрішні інструменти, фронт SaaS. Типізований. Компонентний. Серверний рендеринг як громадянин першого класу, а не латка поверх односторінкового застосунку лише для клієнта.

Ми перейдемо на інший типізований фреймворк — та сама родина, інший бренд — якщо команда, яка успадковує кодову базу, вже знає його краще, ніж наш звичний вибір. Відповідність команді приймання важливіша за відповідність авторам. Завжди.

Ми міцно опиратимемось стекові, в якому фронтенд-фреймворк обрали тому, що він був на головній Hacker News минулого тижня. Це не причина — це настрій.

Бекенд: Python або TypeScript за замовчуванням, Go там, де змагання за ресурси — справжнє обмеження

Python і TypeScript покривають більшість того, що нас просять збудувати. В обох зрілі екосистеми, обидві приємні досвідченим інженерам і посильні для джуніорів, яких клієнт зрештою найме сам, і обидві достатньо швидкі для навантаження майже будь-якого проєкту, який не є біржею високочастотної торгівлі.

Ми тягнемося до Go, коли затримка під змаганням за ресурси — це справжнє обмеження, а не уявне. «Можливо, колись треба буде тримати десять тисяч запитів на секунду» — це уявне. «Наш поточний p95 під навантажувальним тестом подвоюється, коли додаємо п’яту репліку» — справжнє. Не переплачуйте за продуктивність, відсутність якої ще не вмієте виміряти.

Розгортання: контейнери, проста оркестрація, ніякого Kubernetes, якщо він себе не окуповує

Замовчування — це контейнери, зібрані один раз, проведені через середовища і запущені на найпростішій платформі, якої вистачає для масштабу проєкту: часто один VPS зі зворотним проксі, іноді керована контейнерна служба, зрідка маленький флот за балансувальником навантаження. Нудні розгортання. Відтворювані розгортання. Розгортання, які один інженер може налагодити о 2-й ночі з телефона.

Kubernetes — чудовий, коли масштаб команди і масштаб проєкту разом окуповують його вартість. Для більшості проєктів ранньої та середньої стадії — не окуповують, і він з’їдає більше сеньйорського часу, ніж віддає. Ми бачили команди з чотирьох людей, які тримають кластери на п’ятдесят вузлів, бо хтось додав це на другому тижні. З вами такого ми не зробимо.

Чому замовчування важливі — і чому це не те саме, що догма

Замовчування знижують вартість ухвалення рішень у нудних речах, щоб ми могли витрачати свою думку на складні. Це вся гра. Сеньйорська інженерія — це не «кожне рішення з перших принципів, щоразу, у кожному проєкті, для кожного компонента». Це «перші принципи там, де рішення несе вагу для цього проєкту, і стандартна відповідь у всьому іншому».

Студія, яка вважає, що замовчування — це слабкість, спалює своїх найгостріших людей у дискусіях про колір сараю. Студія, яка вважає замовчування непорушними, зрештою постачає стек, що не личить, бо так було зручно. Серединна позиція — сильні замовчування, які з радістю замінюємо, коли проєкт дає причину, — це та, яка реально доставляє.

Це наша позиція. Ми не прикидатимемось, що її в нас немає.

Що можна запитати на першому дзвінку

«Який стек ви візьмете?» — справедливе запитання, і чесна відповідь коротка: залежить, але ось що ми обрали б першим, і ось що змусило б нас обрати щось інше.

Запитуйте. Приносьте ті частини вашого проєкту, які здаються вам нетиповими. Ми скажемо, які з наших замовчувань виживають у контакті з вашими обмеженнями, а які ми замінили б — і чому. Така розмова коротка, продуктивна, і саме така, яку ми проведемо на першому дзвінку — задовго до того, як хтось щось підписуватиме.

Форма доброго проєкту видна вже з цієї розмови. І форма поганого — теж.

Маєте додаток, який має жити?

Виведіть його з прототипу в продакшн.

Відповідаємо протягом одного робочого дня. MVP, написаний на відчуттях, чернетка від AI, недороблений проєкт або робочий продукт, що починає тріщати — усе приймається.

Запустити проєкт