РозробкаБудь-який рівень

Node.js

Node.js — серверне середовище для JavaScript, що виконує весь ваш код в одному потоці й передає кожне очікування операційній системі або невеликому пулу потоків. Саме через цей задум один процес тримає десять тисяч простійних з’єднань — і саме через нього одна повільна функція затримує всі запити одночасно. Сторінка починається з сімнадцяти дій Node-сервера й того, який потік платить за кожну; далі — цикл подій і пул, релізи й підтримка (з Node 27 — один мажорний реліз на рік), що тепер вбудовано, масштабування й коректна зупинка, п’ять задокументованих кейсів і те, де все це вироджується.

Поточна версія
26 · LTS з 28 жовт. 2026
Модель
Один потік для вашого коду
Підтримка
30 місяців LTS; з 27 — мажор на рік

Де виконується кожна робота — сімнадцять дій Node-сервера

Сервер на Java чи Go дає запиту, що чекає, власний потік, тож повільний запит гальмує здебільшого сам себе. Node дає вашому коду рівно один потік. Усі запити процесу по черзі працюють на ньому — ця черговість і є , цикл подій, — а все, що не вміє чекати без потоку, відправляється деінде. Тож корисне питання до будь-якого рядка серверного коду — не «чи він швидкий?», а «який потік за нього платить і хто чекає, поки він виконується?». Ось сімнадцять дій Node-сервера з відповіддю для кожної. Наступні розділи посилаються на рядки за номерами.

#Що робить серверДе це виконуєтьсяХто чекає, поки це триває
1Власний код обробника між двома awaitПотік циклуКожен інший запит у процесі
2JSON.parse() тіла запиту на 20 МБПотік циклуКожен запит — десятки мілісекунд
3Регулярний вираз над даними від користувачаПотік циклуКожен запит — секундами, якщо шаблон робить відкати
4Сортування, фільтрація чи підсумовування великого масивуПотік циклуКожен запит
5Рендеринг HTML на сервері — шаблон, ReactПотік циклуКожен запит
6Будь-який виклик …Sync — readFileSync, pbkdf2Sync, gzipSyncПотік циклуКожен запит — на весь час читання з диска чи обчислення
7console.log у файл або в термінал на LinuxПотік циклу — такий запис синхроннийКожен запит; запис у pipe — асинхронний
8Запит до бази даних мережею — PostgreSQL, MySQL, RedisЯдро ОС — жоден потік не чекаєНіхто; розбір відповіді — знову рядок 1
9Утримання десяти тисяч простійних з’єднань чи WebSocketЯдро ОС — жоден потік не чекаєНіхто; кожне коштує пам’яті, а не потоку
10Таймер — setTimeout, setIntervalПотік циклу, коли спрацьовуєНіхто — але він спрацьовує пізно, поки йдуть рядки 1–7
11Кожен асинхронний виклик fs — readFile, writeFile, statПул потоків — чотири потокиІнші рядки пулу
12dns.lookup() — його викликають http, fetch і більшість драйверів баз даних для кожного імені хостаПул потоків — чотири потокиІнші рядки пулу; повільний DNS-сервер тримає потік на кожен запит імені
13crypto.pbkdf2, scrypt, randomBytes, generateKeyPairПул потоків — чотири потокиІнші рядки пулу
14Асинхронний zlib — gzip і BrotliПул потоків — чотири потокиІнші рядки пулу
15Асинхронна робота нативного доповнення — гешування пакетом bcryptПул потоків, зазвичайІнші рядки пулу
16Воркер worker_threadsВласний потік із власним циклом подійНіхто в основному циклі; дані копіюються туди й назад
17Дочірній процес або споживач, що бере задачі з чергиІнший процесНіхто в цьому процесі

Цикл, що не має права чекати, і пул із чотирьох

Традиційний сервер дає кожному з’єднанню потік, і цей потік стоїть заблокований, поки відповідає база даних. Node взагалі ніколи не блокується на з’єднанні. Він просить операційну систему стежити за всіма сокетами одразу — epoll у Linux, kqueue у macOS, IOCP у Windows — і повідомляти, які з них готові. Тож десять тисяч простійних з’єднань коштують десять тисяч маленьких об’єктів у пам’яті, а не десять тисяч потоків. Коли сокет готовий, libuv — бібліотека на C під Node — ставить його колбек у чергу, і потік циклу його виконує.

Node тримає тисячі з’єднань в одному потоці, бо сам їх не чекає. Мережевий ввід-вивід віддано операційній системі, яка стежить за всіма сокетами одразу й повідомляє про готовність, тож з’єднання коштує пам’яті, а не потоку. Робота, під якою немає асинхронного системного виклику — файли, DNS, стиснення, гешування паролів, — іде в маленький пул, типово на чотири потоки. Ваш власний JavaScript не делеговано нікуди: він виконується в єдиному потоці циклу, тож код, що впирається в CPU, зупиняє всі з’єднання процесу одразу.

Цикл іде по колу фазами: спершу таймери, чий час настав, потім колбеки завершеного вводу-виводу, потім колбеки setImmediate, потім закриті з’єднання — і знову по колу. Між будь-якими двома колбеками він вичерпує чергу виконаних промісів. Правила порядку промісів і таймерів — тема сторінки про JavaScript; для сервера важить один наслідок. Колбек ніколи не переривається. Поки він виконується, цикл не рухається, тож жоден інший запит не розбирається, жодна відповідь не надсилається, жоден таймер не спрацьовує. Тому та сама повільна функція в Java — прикрість, а в Node — аварія.

Вимірювання, що називає цю проблему, — затримка циклу подій: наскільки пізніше, ніж мав, цикл повертається до роботи. perf_hooks.monitorEventLoopDelay(), доступний з Node 11, записує її як гістограму; експортуйте 99-й процентиль як метрику поруч із латентністю. Друге число — завантаженість циклу з performance.eventLoopUtilization() — каже, яку частку часу цикл узагалі був зайнятий. Коли затримка росте, причина — синхронний код у вашому ж процесі (рядки 1–7), і жодне налаштування бази даних її не зрушить. Функцію знаходить профіль процесора: node --cpu-prof записує файл, який Chrome DevTools відкриває як флейм-граф.

Пул із чотирьох і пастка DNS

Для деяких операцій операційна система не має інтерфейсу «скажи, коли буде готово»: читання файлу, пошук імені хоста через системний резолвер, гешування пароля, стиснення відповіді. libuv виконує їх на пулі потоків — рядки 11–15, — і в пулі типово чотири потоки. Документація прямо називає наслідок: якщо будь-яка з цих операцій триває довго, «інші (на перший погляд не пов’язані) , що працюють у пулі потоків libuv, деградуватимуть». Чотири одночасні входи з гешуванням паролів заповнюють пул, і запит, що хотів лише прочитати маленький файл, чекає за ними.

Пастка, яку більшість команд знаходить на власному досвіді, — рядок 12. Пошук імені хоста через dns.lookup() з боку JavaScript виглядає асинхронним, але документація каже, що він «реалізований як синхронний виклик getaddrinfo(3), що виконується в пулі потоків libuv», — а модуль http, fetch і більшість драйверів баз даних викликають його для кожного імені хоста, до якого під’єднуються. DNS-сервер, що відповідає п’ять секунд, тримає потік пулу п’ять секунд на кожен такий пошук. Чотири таких пошуки — і кожне читання файлу в процесі стоїть за ними в черзі, хоча диск простоює, а процесор теж.

Node виконує виклики файлової системи, dns.lookup, асинхронні функції crypto і zlib на одному спільному пулі, типово з чотирьох потоків. Коли два повільні DNS-запити й два гешування паролів займають усі чотири, читання файлу, якому потрібна мілісекунда роботи, секундами чекає за ними — хоча потік циклу вільний, диск простоює, а процесор теж. Пул можна збільшити через UV_THREADPOOL_SIZE, задану в середовищі до старту Node, максимум до 1024 потоків.

Є три виправлення, у порядку того, як часто вони правильні. Перевикористовуйте з’єднання, щоб ім’я хоста розв’язувалося один раз, а не на кожен запит, — це робить агент із keep-alive. Винесіть важке гешування й стиснення зі спільного пулу: у воркер-потік, в окремий сервіс або в бібліотеку з власними потоками. І якщо пул справді має бути більшим, задайте UV_THREADPOOL_SIZE у середовищі до старту Node; максимум — 1024. Задавати його зсередини коду «не гарантовано спрацює», попереджає документація, бо пул створюється раніше, ніж виконується ваш перший рядок.

Що ви бачитеЩо це зазвичай означаєКуди дивитися
Латентність росте для всіх ендпоінтів одразу, одне ядро на 100%Щось тримає потік циклу (рядки 1–7)Затримка циклу, потім профіль процесора
Читання файлів і вихідні виклики гальмують лише під час сплеску входівПул заповнено (рядки 11–15)Скільки гешування й стиснення йде одночасно
Вихідні виклики повільні, а віддалений сервіс звітує, що він швидкийРозв’язання імен у пулі (рядок 12)Латентність DNS; чи перевикористовуються з’єднання
Пам’ять годинами росте, доки контейнер не вб’ютьВитік — зазвичай кеш рівня модуля, слухач чи таймер, які ніхто не прибравДва знімки купи з інтервалом у годину, порівняні між собою
Процес завершується одразу після рядка в лозі про необроблене відхиленняПроміс завершився помилкою, і ніхто його не чекав, — фатально з Node 15Трасування в цьому рядку логу; пропущений await чи .catch()

Релізи: Current, LTS і зміна, що починається цього місяця

До версії 26 Node випускав два мажорні релізи на рік. Парні номери виходили у квітні, непарні — у жовтні. Кожна парна лінія пів року була «Current», а в жовтні ставала лінією — довгострокової підтримки — з 12 місяцями активних виправлень і ще 18 місяцями супроводу: разом 30 місяців. Непарні лінії жили близько восьми місяців і ніколи не отримували LTS. Правило для продакшену випливало саме: запускати парну лінію LTS і оновлюватися до дати кінця її підтримки. Таблиця перелічує, що кожна недавня лінія додала такого, що ви зустрінете в коді, і як довго вона отримує патчі.

ВерсіяВипущеноЩо ви зустрінете в кодіПідтримка до
18квіт. 2022Глобальний fetch без прапорця, експериментальний вбудований тест-ранерЗавершено 30 квіт. 2025
20квіт. 2023Стабільний тест-ранер, модель дозволів як експеримент, --env-fileЗавершено 30 квіт. 2026
22квіт. 2024require() ES-модулів, клієнт WebSocket, стабільний --watch, node --run, node:sqlite, TypeScript-файли запускаються напряму30 квіт. 2027
24трав. 2025npm 11, URLPattern як глобальний об’єкт, оголошення using, стабільне видалення типів30 квіт. 2028
26трав. 2026Temporal увімкнено за замовчуванням, Undici 8, --experimental-transform-types прибрано30 квіт. 2029
27Alpha з 28 жовт. 2026; 27.0.0 у квіт. 2027Перша лінія за новим розкладом; тайм-аут keep-alive 65 с за замовчуванням30 квіт. 2030
До версії 26 Node щоквітня випускав парну лінію, а щожовтня — непарну; LTS ставали лише парні, з 12 місяцями активної підтримки й 18 — супроводу. Версія 25, остання непарна, завершилася в червні 2026 року, так і не ставши LTS. З 27 мажорна лінія одна на рік: Alpha з жовтня, Current з квітня, далі 30 місяців LTS — і LTS стає кожна лінія. Node 26, що переходить у LTS 28 жовтня 2026 року, — остання лінія за старою моделлю.

Що тепер вбудовано: модулі, TypeScript і менше пакетів

У Node дві системи модулів, і більшість проєктів досі зустрічає обидві. CommonJS — require() і module.exports — початкова, вона розв’язується під час виконання коду. ES-модулі — import і export — стандарт мови. Роками межа між ними була стіною: файл CommonJS не міг зробити require() ES-модуля, тож одна залежність, що перейшла лише на ESM, змушувала своїх користувачів мігрувати. З Node 22.12 і 20.19 це працює без прапорця, а з 25.4 — стабільно. Лишився один виняток: модуль із await верхнього рівня так завантажити не можна, і виклик падає з ERR_REQUIRE_ASYNC_MODULE. Новий код має бути на ES-модулях, з "type": "module" у package.json.

Node тепер також запускає -файли напряму: за замовчуванням з 22.18, стабільно з 24.12. Варто точно знати, що це означає, бо назва обіцяє більше, ніж є. Node видаляє анотації типів — замінює їх пробілами — і виконує те, що лишилося. Перевірки типів немає зовсім, тож код із помилкою типів однаково запускається. tsconfig.json ігнорується, тож псевдоніми шляхів не розв’язуються. Підтримується лише синтаксис, який можна стерти: enum чи властивість-параметр конструктора потребують згенерованого коду й відхиляються. І TypeScript-файли всередині node_modules Node обробляти відмовляється, тож пакети далі публікують JavaScript. Лишіть tsc --noEmit у збірці: Node замінює крок виводу компілятора, а не його перевірку.

Пакет, який може вже не знадобитисяЩо вбудовано натомістьЗ версії
node-fetch, axios для простих викликівГлобальний fetch18; стабільний у 21
jest, mocha для власних тестів бібліотекиnode:test і node --testСтабільний у 20
nodemonnode --watchСтабільний у 22
dotenvnode --env-file=.env20.6; стабільний у 24.10
ts-node, tsx для коду без enumВидалення типів22.18; стабільне в 24.12
ws як клієнтГлобальний WebSocket22
npm run лише щоб запустити скриптnode --run22
better-sqlite3node:sqlite22.5; ще не стабільний

Саме на етапі встановлення живе справжній ризик ланцюга постачання в Node, і це інший ризик, ніж той, що описує сторінка про JavaScript. Та сторінка — про дерево залежностей, тобто про те, що ви постачаєте користувачам. Ця — про те, що виконується на вашій машині. npm install запускає скрипти preinstall, install і postinstall кожного пакета з правами вашого користувача: на ноутбуці, де є ключі SSH, на сервері збірки, що тримає облікові дані хмари. Три заходи закривають більшу частину ризику. Встановлюйте через npm ci із закоміченого . Запускайте це з --ignore-scripts у конвеєрі й дозволяйте скрипти лише кільком пакетам, що компілюють нативний код. Або візьміть pnpm, який з версії 10, із січня 2025 року, не запускає скриптів залежностей, якщо їх не перелічено.

Масштабування, падіння і коректна зупинка

Один процес Node використовує для вашого коду одне ядро, тож шістнадцятиядерна машина з одним процесом використовує одну шістнадцяту того, за що ви заплатили. Виходів три, і вони не взаємозамінні: кожен пасує іншій формі задачі.

ПідхідЩо цеКоли брати
Більше процесівN копій за балансувальником навантаження — на практиці один процес на контейнер, а репліки додає оркестратор.Майже завжди. Це типова відповідь для HTTP-сервісу без стану.
worker_threads (рядок 16)Справжні потоки в одному процесі, кожен із власним циклом подій і без спільних змінних.Одна важка операція всередині сервісу, що загалом чекає, — PDF, зображення, великий розбір.
Черга (рядок 17)Покласти задачу до брокера й дати окремому процесу-споживачу її виконати.Робота, що може завершитися після відповіді: звіти, листи, медіа, імпорти.

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

Коректна зупинка і 502, який ніхто не може відтворити

Оркестратор зупиняє контейнер, надсилаючи SIGTERM, а після пільгового періоду — у Kubernetes типово тридцять секунд — убиває його. Процес, що ігнорує сигнал, на кожному деплої втрачає всі запити в польоті. Обробіть його: викличте server.close(), що перестає приймати з’єднання, а з Node 19 ще й закриває простійні; дайте запитам у польоті завершитися; закрийте пул з’єднань із базою; вийдіть із запасом до кінця пільгового періоду.

Другий збій не потребує жодного деплою. Балансувальник навантаження тримає простійні з’єднання з вашим процесом відкритими, щоб перевикористати їх для наступного запиту. Application Load Balancer в AWS типово тримає їх 60 секунд. Node закриває простійне з’єднання після свого keepAliveTimeout — типово 5 секунд, плюс секунда запасу з 24.6 і 22.19. Тож Node завжди закриває першим. Здебільшого це нешкідливо. Але коли балансувальник надсилає запит у з’єднання саме тієї миті, коли Node його закриває, запит натрапляє на сокет, що закривається, і клієнт отримує 502 Bad Gateway. AWS документує саме це й радить, щоб тайм-аут простою застосунку був довшим за тайм-аут балансувальника.

Балансувальник навантаження тримає простійні з’єднання з цілями відкритими, щоб перевикористати їх; Application Load Balancer в AWS типово тримає їх 60 секунд. Node закриває простійне з’єднання після свого keepAliveTimeout — типово 5 секунд, плюс секунда запасу з 24.6 і 22.19, — тож завжди закриває першим. Коли балансувальник надсилає запит у з’єднання саме тієї миті, коли Node його закриває, клієнт отримує 502 Bad Gateway: рідко й ніколи на тихому тестовому середовищі. keepAliveTimeout, довший за тайм-аут простою балансувальника, наприклад 65 секунд, змушує балансувальник закривати першим; з Node 27 це значення за замовчуванням.

Дорогим його робить симптом: кілька 502 на багато тисяч запитів, жодної помилки в лозі застосунку й нічого на тихому тестовому середовищі, бо гонці потрібен справжній трафік, щоб влучити в точну мить. Виправлення — один рядок: server.keepAliveTimeout = 65_000, довше за 60 секунд балансувальника, — і сам Node з версії 27 дотримується того самого погляду: 65 секунд стають значенням за замовчуванням. До того кожному сервісу за балансувальником потрібен цей рядок.

П’ять кейсів і те, чого в кожному бракувало

Кожен кейс задокументували ті, з ким він стався: інженерні блоги, власний журнал змін і записи релізів проєкту, бюлетень безпеки, оголошення реєстру. Разом вони покривають ставку, яку робить Node, його врядування, цикл, залежність на циклі й етап встановлення.

КейсЩо сталосяЧого бракувало
PayPal, 2013Та сама сторінка на Java і на Node: удвічі більше запитів за секунду на одному ядрі проти п’ятиНічого — але результат стосується сторінок, що чекають, і допис так і каже
io.js, 2014–2015Контриб’ютори форкнули Node через врядування й завмерлий ритм релізів; проєкти злилися в Node 4Відкрите врядування й передбачуваний розклад
Netflix, лист. 2014Латентність росла на 10 мс щогодини до перезапусків — через дублікати обробників маршрутівПрофіль процесора для циклу
path-to-regexp, вер. 2024Один підготовлений URL тримав цикл будь-якого застосунку на Express 4 із маршрутом /:a-:bШаблон без відкатів і обмеження довжини URL
Shai-Hulud, вер. і лист. 2025Хробак поширювався через скрипти встановлення npm, крав токени й публікував сам себеВимкнені за замовчуванням скрипти встановлення, короткоживучі токени публікації

Перший кейс — сама ставка, виміряна чесно. У 2013 році PayPal переписав на Node сторінку огляду рахунку, одну з найнавантаженіших на сайті, а команда паралельно будувала ту саму сторінку на Java, на власному фреймворку на основі Spring, як запасний варіант. Обидві пройшли ті самі функціональні тести. У листопаді 2013 року Джефф Гаррелл опублікував цифри: версію на Node збудували майже вдвічі швидше меншою командою, і вона обслуговувала вдвічі більше запитів за секунду — «з одним ядром для застосунку на node.js проти п’яти ядер у Java», — з середнім часом відповіді на 35% меншим, приблизно на 200 мс. Деталь, що це пояснює, — у тому самому дописі: кожен із трьох маршрутів сторінки робив від двох до п’яти запитів до API і зшивав відповіді. Це рядки 8 і 9: сторінка, що все життя чекає. Допис закінчується власним застереженням — «у вас може бути інакше», — і воно слушне. Те саме переписування сторінки, що обчислює, показало б протилежне.

Третій кейс — рядок 1, схований усередині фреймворку. У листопаді 2014 року Юнонг Сяо описав у Netflix Tech Blog Node-сервіс, латентність якого починалася з 1 мс і росла на 10 мс щогодини, сягаючи близько 60 мс, перш ніж інстанси перезапускали. Разом із нею ріс і процесор. Власні обробники команди стабільно показували 1 мс, а купа трималася біля 1,2 ГБ, тож винні не були ні їхній код, ні витік пам’яті у звичному сенсі. Флейм-граф процесора показав дуже високі стеки всередині маршрутизатора Express. Express тримав усі обробники маршрутів в одному масиві й проходив його на кожен запит. Завдання в коді Netflix десять разів на годину оновлювало маршрути із зовнішнього джерела — і щоразу ще й додавало той самий обробник статичних файлів, попереду маршрутів API. Кожен дублікат коштував близько 1 мс на кожному запиті: десять за годину — 10 мс за годину. Ніщо не падало; цикл просто щогодини робив на запит більше роботи. Поступові перезапуски це ховали. Профіль знайшов.

П’ятий кейс — етап встановлення. 14 вересня 2025 року GitHub повідомили про Shai-Hulud — хробака, що сам себе відтворював: він потрапив у npm через зламані облікові записи мейнтейнерів і вставляв у їхні пакети скрипти post-install. Коли розробник чи сервер збірки встановлював заражену версію, скрипт шукав на машині секрети — серед них токени npm і облікові дані хмари — і з кожним знайденим токеном npm публікував заражені версії інших пакетів того самого мейнтейнера. GitHub видалив понад 500 пакетів. 22 вересня він оголосив зміну моделі: локальна публікація з двофакторною автентифікацією, гранулярні токени, що живуть сім днів, довірена публікація із систем збірки й відмова від класичних токенів. Друга хвиля в листопаді 2025 року перейшла на preinstall — він виконується ще до повного встановлення пакета, — зачепила близько 700 пакетів і лишила понад 25 000 репозиторіїв GitHub з украденими секретами. Кожне зараження починалося однаково: скрипт встановлення, що працює з правами того, хто набрав npm install.

Де він вироджується

Модель Node безжальна в один бік і щедра в інший. Чекання майже безкоштовне, тож сервіс, що лише чекає, на одному процесі масштабується далі, ніж більшість середовищ на двадцяти потоках. Обчислення ділять усі, тож один необережний рядок оподатковує всіх користувачів одразу. Майже кожен збій — це один із сімнадцяти рядків, поставлений не в той потік:

  • Розбір, сортування, рендеринг чи гешування в потоці циклу гальмує кожен паралельний запит (рядки 1–6).
  • Регулярний вираз, написаний вручну й застосований до вводу користувача без обмеження довжини (рядок 3).
  • Гешування паролів, стиснення й DNS, що б’ються за чотири потоки пулу (рядки 11–15).
  • Жодної метрики затримки циклу, тож єдине число, що пояснює сповільнення, ніколи не потрапляє на дашборд.
  • Стан у змінній рівня модуля, що тихо розходиться тієї миті, коли з’являється другий процес.
  • Глобальний обробник, що ковтає помилки й лишає процес працювати в невідомому стані.
  • Жодного обробника SIGTERM, тож кожен деплой обриває запити в польоті.
  • Тайм-аут keep-alive за замовчуванням за балансувальником, що виявляється рідкісними 502, які ніхто не може відтворити.
  • Скрипти встановлення, що виконуються на серверах збірки, які тримають токени публікації й облікові дані хмари.
  • Лінія після дати кінця підтримки — сьогодні це все, що старше за 22.

Чесна межа — сам єдиний потік. Сервіс, чиї запити обчислюють, а не чекають, — обробка зображень, аналітика, важкі перетворення, — бореться з моделлю на кожному кроці. Воркер-потоки й черги виносять роботу назовні, але тоді більша частина сервісу написана довкола того, щоб забрати роботу від Node, і середовище зі справжніми потоками чи компільована мова були б простішим вибором. Справедливе й протилежне: причини, з яких команди йдуть із Node, часто виявляються рядками 1–7, які профіль знайшов би за один день.

Практична перевірка займає п’ять хвилин. Запустіть node -v у продакшн-образі й знайдіть рядок у таблиці релізів. Перевірте, що затримка циклу подій експортується, і подивіться на її 99-й процентиль у пік. Порівняйте keepAliveTimeout з тайм-аутом простою балансувальника. І подивіться, як конвеєр встановлює залежності: npm ci, зі скриптами вимкненими, з lockfile.

Коли це застосовувати

Застосовуйте, коли

  • API та шлюзи, чия робота — викликати інші системи й формувати їхні відповіді.
  • Реальний час — , потоки, довгі з’єднання, — де тримати багато простійних сокетів дешево.
  • Команди, які вже пишуть фронтенд на TypeScript: вони отримують спільні типи й один інструментарій з обох боків.
  • Застосунки з рендерингом JavaScript на сервері, де фреймворку середовище Node потрібне так чи інакше.

Уникайте, коли

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

Джерела й метод

На чому стоїть ця стаття

  • 19 джерел
  • 3 задокументовані збої
  • Перевірено 13 жовтня 2026 р.

Практики й походження термінів

який потік платить за кожну операцію, і графік релізів

Дослідження з Claude. Пошук і звірку першоджерел зроблено з Claude (Anthropic). Відбір, текст і перевірку фактів — редакція Anatomy of IT Product.

Було корисно?

Поділіться з тим, хто працює над тією ж задачею.