Czego szukamy w Senior Node.js developera
Senior Node.js developer w 2026 roku to przede wszystkim ktoś, kto rozumie, że Node.js 22 LTS dał ekosystemowi natywny test runner, built-in fetch, stable WebSocket API i ulepszone wsparcie dla worker threads — a mimo to wciąż większość praktycznej wiedzy leży w bibliotekach. Dobry kandydat porusza się sprawnie po TypeScript 5.x, świadomie konfiguruje tsconfig.json (strict mode, paths, moduleResolution: “bundler” lub “nodenext”), wie kiedy używać Express.js (legacy, prosty middleware), kiedy Fastify (wydajność, schema validation, plugin system), a kiedy pełnoprawnego NestJS (architektura modułowa, DI, decoratory, integracja z mikroserwisami). Powinien znać Koa jako lekką alternatywę, ale też rozumieć kompromisy — duża społeczność Express vs nowoczesność Fastify vs strukturalna ciężkość Nest.
W ARDURA Consulting szukamy także świadomości warstw persystencji. Senior Node.js to ktoś, kto potrafi uzasadnić wybór między Prismą (świetny DX, type safety, migracje), TypeORM (klasyczny, decoratory, dojrzały) i Drizzle ORM (lekki, bliski SQL, edge-friendly). Po stronie NoSQL — Mongoose dla MongoDB (z dobrze zdefiniowanymi schematami i indeksami), ioredis do Redis z connection poolingiem i Pub/Sub, BullMQ do kolejek zadań. Musi rozumieć event loop, microtasks vs macrotasks, blocking operations, worker threads i child_process — wiedza, która oddziela seniora od midu. I wreszcie observability: structured logs w Pino lub Winston, OpenTelemetry traces i metryki, integracja z systemami typu Grafana, Datadog, New Relic.
Top 15 pytań rekrutacyjnych z odpowiedziami
1. Jak działa event loop w Node.js 22 i jakie są jego fazy?
Fazy: timers, pending callbacks, idle/prepare, poll, check (setImmediate), close callbacks. Pomiędzy każdą fazą process.nextTick i Promise microtasks. Senior wyjaśni, jak setImmediate różni się od setTimeout(fn, 0) oraz dlaczego process.nextTick może zablokować I/O.
2. Kiedy używać worker threads, kiedy child_process, a kiedy klastra? Worker threads — operacje CPU-bound w tym samym procesie (parsing, kompresja). Child_process — uruchamianie osobnych binariów lub skryptów. Cluster — skalowanie HTTP servera na wielu rdzeniach (choć dziś częściej kontener orkiestrator robi to za nas).
3. Jak obsłużyć błędy w async/await — pattern dla aplikacji produkcyjnej?
Try/catch na granicach (kontroler, handler komendy). Globalny error handler w Express/Fastify/Nest. Brak silent failures — każdy await musi mieć ścieżkę błędu. unhandledRejection zalogować i zakończyć proces (let it crash, restartuje go orchestrator).
4. Express vs Fastify vs NestJS — kiedy co? Express: legacy, prosty middleware, ogromna społeczność. Fastify: 2-3x szybszy, schema validation przez JSON Schema, plugin system. Nest: duże aplikacje enterprise, DI, modułowość, integracja z gRPC, GraphQL, mikroserwisami. Senior nie odpowiada „Nest jest najlepszy” — odpowiada „zależy”.
5. Co to jest Prisma i jak różni się od TypeORM i Drizzle? Prisma: query builder oparty o schema.prisma, świetny DX, type safety, migracje, klient generowany. TypeORM: klasyczny ORM z dekoratorami, ActiveRecord lub DataMapper, więcej magii, mniej kontroli. Drizzle: minimalistyczny, bliski SQL-owi, edge-runtime friendly, mniej abstrakcji.
6. Czym jest BullMQ i kiedy go używamy? Biblioteka kolejek oparta o Redis. Job queue, repeatable jobs, priorytety, rate limiting. Stosujemy do: wysyłki maili, generowania raportów, scrapowania, integracji asynchronicznych. Senior wskaże alternatywy — RabbitMQ z amqplib, Kafka z kafkajs.
7. Jak działa Socket.io i czym różni się od czystego WebSocketa?
Socket.io to abstrakcja nad WebSocketami z fallbackiem (long polling), z roomami, namespace’ami, ack callbackami, automatyczną reconnection. Czysty WebSocket (np. przez ws lub Bun WebSocket) — lżejszy, ale bez gotowych prymitywów chatowych.
8. Jak skonfigurować monorepo z pnpm workspaces lub Turborepo?
Workspaces w pnpm-workspace.yaml. Turborepo dodaje równoległy task runner z cache (lokalny i remote). Senior porówna z NX (mocniejszy generator code, dependency graph, ale ciężej w setupie).
9. Jak działa Apollo GraphQL Server v4 i jak rozwiązać problem N+1?
Apollo Server 4 to express/fastify middleware. N+1 rozwiązujemy przez DataLoader — batchowanie i cache per request. Senior wymieni też alternatywy: subscriptions przez graphql-ws, federacja, schema stitching.
10. Jak skonfigurować observability w Node.js? Pino do structured logs (znacznie szybszy od Winstona), OpenTelemetry SDK do traces i metryk (auto-instrumentation dla Express/Fastify/HTTP), eksport do Jaeger lub Tempo. Senior dorzuci correlation ID propagation i log redaction dla danych wrażliwych.
11. Co to jest gRPC i jak go używać w Node.js?
gRPC działa na HTTP/2 z Protocol Buffers. W Node używamy @grpc/grpc-js. Generujemy typy z .proto przez ts-proto. Świetny do service-to-service. REST zostaje dla publicznych API i klientów web.
12. Jak budować i deployować mikroserwis Node.js w kontenerze?
Multi-stage Dockerfile (build → distroless lub alpine), NODE_ENV=production, npm ci --omit=dev, healthcheck endpoint, graceful shutdown na SIGTERM. Senior wspomni o pm2 na bare metal i o tym, że w Kubernetes pm2 jest niepotrzebny (zarządza tym kubelet).
13. Jak testować aplikację Node.js — Vitest, Jest czy Mocha? Vitest: szybki, ESM-first, kompatybilny z Jest API, dobrze działa z TypeScript przez Vite. Jest: dojrzały, ale wolniejszy. Mocha: minimalistyczny, sam dobierasz assertion library (Chai) i mocks (Sinon). Do testów HTTP: Supertest. Do mockowania: msw lub nock.
14. Czym jest Drizzle ORM i dlaczego rośnie popularnością? Lekki ORM bliski SQL, zero magii, edge-runtime friendly (Vercel Edge, Cloudflare Workers), pełna kontrola nad zapytaniami, doskonała type safety. Senior wskaże ograniczenia — mniejsza społeczność, młodszy ekosystem.
15. Jak obsłużyć graceful shutdown w aplikacji produkcyjnej?
Listener na SIGTERM/SIGINT, zatrzymanie przyjmowania nowych połączeń (server.close()), drain BullMQ workers, zamknięcie połączeń DB (Prisma disconnect), close Redis. Timeout (30 s) — po nim forced exit. Senior podkreśli, że bez graceful shutdown utracimy in-flight requests przy każdym deployu.
Zadania techniczne — 3 scenariusze
Scenariusz 1 — REST API w Fastify z TypeScript, Prismą i testami w Vitest.
Zadanie: zbudować mikroserwis do zarządzania zamówieniami z endpointami CRUD, walidacją przez JSON Schema (lub Zod), Prismą jako warstwą danych, autoryzacją JWT i testami integracyjnymi w Vitest + Supertest. Oceniamy: separację warstw (route → service → repository), poprawność transakcji (prisma.$transaction), strukturę testów (faktory, izolację bazą testową przez Testcontainers), handling błędów (mapowanie wyjątków na statusy HTTP). Senior pokaże, że zna pluginy Fastify (@fastify/swagger, @fastify/jwt) i potrafi je hermetyzować w modułach.
Scenariusz 2 — Worker w BullMQ z retry i obserwowalnością. Pokazujemy use case: serwis wysyła maile transakcyjne, ale dostawca SMTP ma okazjonalne timeouty. Zadanie: zaprojektować job queue w BullMQ (Redis), z exponential backoff (5 prób), idempotencją (idempotency key), poison queue dla trwałych błędów. Dodać structured logs w Pino, traces w OpenTelemetry, metryki (jobs/s, failure rate). Oceniamy: rozumienie at-least-once delivery, prawidłowe odróżnienie retryable od non-retryable errors, jakość observability. Senior zaproponuje też dashboard w Grafanie i alert na rosnący failed rate.
Scenariusz 3 — Realtime z Socket.io lub Apollo GraphQL Subscriptions.
Klient potrzebuje notyfikacji w czasie rzeczywistym (dashboard live, nowy event z BullMQ workera). Zadanie: zbudować warstwę realtime — albo Socket.io z roomami per użytkownik, albo Apollo Subscriptions przez graphql-ws, plus Redis Pub/Sub jako broker między instancjami. Oceniamy: skalowalność horyzontalną (sticky sessions, Redis adapter dla Socket.io), autentykację przy handshake, czystość kodu po stronie klienta i serwera, testowalność. Senior zauważy, że WebSocket wymaga sticky sessions w load balancerze albo Redis adaptera i opisze koszt każdego rozwiązania.
Red flags
Pierwszy sygnał ostrzegawczy w rozmowie rekrutacyjnej — brak rozumienia event loop. Kandydat, który mówi „Node jest single-threaded więc jest wolny”, nie rozumie modelu i prawdopodobnie pisze kod blokujący główny wątek. Drugi — używanie callbacków zamiast async/await bez argumentacji (legacy code OK, nowy kod bez async/await to czerwona flaga). Trzeci — brak doświadczenia z TypeScriptem na sensownym poziomie strict (kandydat nie wie czym jest unknown vs any, nie używa narrowing). Dalej: bezrefleksyjne sięganie po Express w nowych projektach, ignorowanie obserwowalności (console.log jako logger w produkcji), brak testów lub testy tylko na happy path. Czerwona lampka zapala się, gdy kandydat nie zna kompromisów Prismy vs Drizzle vs TypeORM i mówi „Prisma zawsze”. Brak doświadczenia z kolejkami (BullMQ, RabbitMQ, Kafka) u kogoś, kto deklaruje pracę z mikroserwisami, jest podejrzany. Wreszcie: nieumiejętność opowiedzenia o graceful shutdown i o tym co dzieje się z in-flight requestami przy deployu — to differentiator między midem a seniorem. Dodatkowo: stosowanie JSON.parse na nieufnym inpucie bez obsługi błędów, brak wiedzy o memory leakach (event listenery, closures, niezakończone streamy), używanie console.log jako loggera produkcyjnego oraz brak doświadczenia z Dockerfile multi-stage i graceful shutdown w kontenerze.
Jak ARDURA Consulting weryfikuje kandydatów
W ARDURA Consulting prowadzimy trzyetapową weryfikację Senior Node.js developera w 5 dni roboczych. Etap pierwszy — rozmowa techniczna z naszym Tech Leadem (60 minut, 15 pytań kalibrowanych do stacka klienta: Express/Fastify/Nest, Prisma/TypeORM/Drizzle, BullMQ/Kafka, observability). Etap drugi — zadanie praktyczne (90 minut live coding lub take-home na 4-6 godzin), gdzie oceniamy strukturę kodu, świadomość event loop, jakość testów, obsługę błędów i obserwowalność. Etap trzeci — rozmowa kulturowo-biznesowa z klientem, fit zespołowy i zrozumienie domeny.
W bazie mamy seniorów z doświadczeniem w pełnym spektrum projektów node’owych — od backendów obsługujących setki tysięcy requestów na sekundę przez Fastify, przez systemy event-driven oparte o Kafkę i BullMQ, po architektury serverless w AWS Lambda i Vercel Edge Functions. Każdy z naszych ekspertów ma potwierdzone wdrożenia produkcyjne z observability w stacku OpenTelemetry, Grafana, Datadog. W procesie weryfikacji szczególnie pilnujemy dwóch obszarów, w których najczęściej wypadają midowie podszywający się pod seniorów: graceful shutdown i obsługa edge case’ów w event loop. Te dwa pytania filtrują ponad połowę kandydatów. Sprawdzamy też portfolio repozytoriów i kontrybucje open source — wielu naszych seniorów to autorzy bibliotek npm używanych przez społeczność.
Dzięki bazie ponad 500 sprawdzonych seniorów IT i 99% retencji prezentujemy 2-3 dopasowanych kandydatów w 14 dni z dwutygodniowym onboardingiem. Średnia oszczędność klienta na pełnym procesie rekrutacyjnym vs in-house — 40%. Współpracujemy w modelu Time & Materials, fixed scope lub Dedicated Team — w zależności od potrzeb klienta i etapu projektu. Sprawdź dostępnych ekspertów →