TypeScript + Python: один інженер, дві екосистеми, один контракт

2026-09-10

Дедалі більше продуктів, над якими я працюю, мають дві половини. Одна - те, чого торкаються люди: інтерфейс на Next.js, API на Node.js, авторизація, платежі. Друга - робота з моделями: інференс, ембеддинги, аудіо, обробка даних. Перша половина говорить TypeScript, друга - Python. Володіти обома - це не про колекцію мов, а про відповідальність за стик між ними, бо саме там ламається більшість AI-продуктів.

Добра новина: ці екосистеми віддзеркалюють одна одну більше, ніж здається. У Zod є Pydantic. У tsc - mypy і pyright. В ESLint і Prettier - Ruff. У npm і pnpm - uv і Poetry. В Express і NestJS - FastAPI, який ще й генерує OpenAPI з типізованих моделей з коробки. Я приношу ту саму дисципліну в обидві сторони: суворі типи, форматер, з яким ніхто не сперечається, зафіксовані залежності й тести в CI.

Контракт між ними - найважливіший файл у системі. Описую його один раз, а решту генерую: Pydantic-моделі у FastAPI дають OpenAPI-схему, а з неї генеруються TypeScript-клієнт і типи. Перейменували поле в Python - і збірка Next.js падає раніше, ніж користувач побачить undefined. Для асинхронної роботи контракт - це payload задачі зі схемою з обох боків, а не довільний JSON, який кожна сторона тлумачить по-своєму.

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

Різниця між ними теж важлива, і поважати її - частина роботи. У Python прототипують у ноутбуці, але ноутбук - не продакшен: робочий код переїжджає в модуль з тестами. Конкурентність у Python - не event loop з Node: важкий для CPU інференс іде в окремі процеси чи GPU-сервіс, а не в async-обробник запиту. І одиниці деплою різні - легкий Node-образ проти Python-образу з CUDA й вагами моделі - тож вони по-різному масштабуються, кешуються й коштують.

Для клієнта цінність одного інженера на обох сторонах проста: немає перекладача між «людиною з AI» і «людиною з вебу», немає API, в якому кожна сторона звинувачує іншу. Якщо у вашому продукті є модель, яка працює в ноутбуці, і вебзастосунок, який ще не вміє нею користуватись, - надішліть обидва. Відповім контрактом, який поставив би між ними, і першою версією, яку б відвантажив.

Дайте наступному продукту того, хто лишається.

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

Запитайте про досвід чи послуги