TypeScript + Python: jeden inżynier, dwa ekosystemy, jeden kontrakt

2026-09-10

Coraz więcej produktów, nad którymi pracuję, składa się z dwóch części. Pierwsza to elementy używane przez ludzi: interfejs Next.js, API Node.js, uwierzytelnianie i płatności. Druga obejmuje pracę z modelami: inferencję, embeddingi, audio i przetwarzanie danych. Pierwsza część mówi w TypeScripcie, druga w Pythonie. Biegłość w obu językach nie polega na ich kolekcjonowaniu, lecz na przejęciu odpowiedzialności za styk między nimi — dokładnie tam psuje się wiele produktów AI.

Dobra wiadomość jest taka, że oba ekosystemy mają więcej wspólnego, niż się wydaje. Odpowiednikami Zod są Pydantic, tsc — mypy i pyright, ESLint i Prettier — Ruff, a npm i pnpm — uv i Poetry. FastAPI pełni podobną funkcję co Express i NestJS, a do tego generuje OpenAPI z typowanych modeli. Po obu stronach stosuję tę samą dyscyplinę: ścisłe typy, bezdyskusyjny formatter, przypięte zależności i testy w CI.

Kontrakt między nimi to najważniejszy plik systemu. Definiuję go raz i generuję resztę: modele Pydantic w FastAPI tworzą schemat OpenAPI, z którego powstają klient TypeScript i jego typy. Zmiana nazwy pola w Pythonie powoduje błąd buildu Next.js, zanim użytkownik zobaczy undefined. Przy pracy asynchronicznej kontraktem jest payload zadania ze schematem po obu stronach, a nie dowolny JSON, który każda interpretuje po swojemu.

Podział odpowiedzialności pozostaje ścisły. TypeScript odpowiada za tożsamość, uprawnienia, pieniądze i UI. Python odpowiada wyłącznie za model: przyjmuje zadanie, wykonuje ciężką pracę — generowanie głosu StyleTTS2, przetwarzanie partii embeddingów czy analizę dokumentu — i zwraca wynik. Usługa Python nigdy nie rozmawia z przeglądarką ani nie decyduje, kto może co zrobić. Szybkie wywołania idą przez HTTP, wolne przez kolejkę; po obu stronach są limity czasu, ponowienia i idempotencja.

Różnice też mają znaczenie i trzeba je respektować. W Pythonie można prototypować w notebooku, ale notebook nie jest środowiskiem produkcyjnym — gotowy kod trafia do modułu z testami. Współbieżność Pythona to nie event loop Node: inferencja obciążająca CPU powinna działać w procesach workerów lub usłudze GPU, a nie w asynchronicznym handlerze żądania. Inne są też artefakty wdrożeniowe — lekki obraz Node kontra obraz Pythona z CUDA i wagami modelu — więc różnią się skalowanie, cache i koszty.

Dla klienta wartość jednego inżyniera po obu stronach jest prosta: nie potrzeba warstwy tłumaczącej między „osobą od AI” a „osobą od webu” ani API, za które każda strona obwinia drugą. Jeśli masz model działający w notebooku i aplikację webową, która jeszcze nie umie z niego korzystać, prześlij mi oba elementy. Zaproponuję kontrakt między nimi i pierwszą wersję, którą wdrożyłbym produkcyjnie.

Daj kolejnemu produktowi kogoś, kto zostanie.

Chcesz zacząć? Napisz do mnie — mogę rozpocząć od razu i zostać na dłużej. Długoterminowa współpraca, nie przekazanie projektu po dwóch tygodniach. Omówmy projekt, wymagania i najlepszy sposób realizacji.

Zapytaj o doświadczenie lub usługi