HostiServer
2026-05-31 20:10
Node.js та NPM у 2026: Event Loop, продакшн-стек, порівняння з PHP та Python
Node.js та NPM: від «Hello World» до високонавантажених систем
Якщо ваш бекенд "заїкається" при кожному запиті до бази даних — користувач не чекатиме. Він піде до конкурентів. Node.js став стандартом для побудови швидких масштабованих сервісів, а NPM — інструмент який дозволяє не писати з нуля те, що вже давно написано і відтестовано спільнотою.
Типова ситуація: ви запускаєте API для мобільного додатка або сервіс моніторингу. Традиційний синхронний стек обробляє запити послідовно — поки один чекає відповіді від бази, решта стоять у черзі. Node.js працює інакше: відправляє запит до бази, не чекає, переходить до наступного завдання, і повертається до результату коли той готовий. На VPS з 4 vCPU Express-додаток на Node.js видає 1200-1500 RPS — це в 4-5 разів більше ніж PHP-FPM з Laravel на тому ж залізі.
Що таке Node.js
Node.js — не мова програмування, а середовище виконання. Воно бере рушій V8 (той самий, що в Google Chrome) і дозволяє JavaScript працювати на сервері.
Неблокуючий ввід/вивід. Node.js не зупиняється поки файл записується на диск або поки прийде відповідь від зовнішнього API. Він ставить задачу у чергу і переходить до наступної. Коли результат готовий — повертається до нього.
Масштабованість. Ідеально підходить для мікросервісів, чатів, стрімінгів та систем реального часу. Uber, Netflix, PayPal — усі побудовані на Node.js не тому що це модно, а тому що архітектура Event Loop дозволяє одному процесу обробляти тисячі одночасних з'єднань без створення окремого потоку на кожне.
Єдиний стек. JavaScript і на фронтенді, і на бекенді. Це не просто зручність — це менше перемикань контексту для розробника, спільні утиліти між клієнтом і сервером, і один package.json для всього проєкту у monorepo-підході.
Event Loop: ядро продуктивності Node.js
Щоб зрозуміти чому Node.js швидкий на I/O-задачах, потрібно розуміти Event Loop. Це не абстракція — це конкретний механізм, який визначає як виконується кожен рядок вашого коду.
Схема показує три компоненти які працюють разом:
Call Stack — стек викликів. Сюди потрапляють функції які виконуються прямо зараз. JavaScript однопотоковий, тому Call Stack один — функції виконуються по черзі.
WebAPIs / libuv — коли код натикається на асинхронну операцію (запит до бази, читання файлу, setTimeout), вона передається сюди. Call Stack не чекає — він вільний для наступної задачі.
Callback Queue — коли асинхронна операція завершилась, її callback потрапляє у чергу. Event Loop постійно перевіряє: якщо Call Stack порожній — бере наступний callback з черги і ставить у стек на виконання.
Результат: поки один запит чекає відповіді від PostgreSQL (це 5-50 мс), Node.js встигає обробити сотні інших запитів. Саме тому один процес Node.js тримає навантаження яке потребувало б десятків потоків у традиційній моделі "потік на запит".
🚨 Головна пастка Event Loop: Якщо покласти у Call Stack важку синхронну операцію — наприклад, генерацію PDF на 500 сторінок або обробку зображення — весь Event Loop зупиняється. Усі інші запити чекають поки ця операція закінчиться. Тому CPU-bound задачі у Node.js виносять у Worker Threads або окремі процеси через BullMQ.
NPM: найбільший реєстр пакетів у світі
NPM (Node Package Manager) — менеджер залежностей який встановлюється разом з Node.js. На момент 2026 року у реєстрі NPM понад 2.5 мільйона пакетів — це найбільша екосистема програмного забезпечення в історії.
Замість того щоб тиждень писати систему авторизації або обробник зображень — одна команда в терміналі:
# Фреймворк для API
npm install express
# Валідація та санітизація вхідних даних
npm install joi
# ORM для PostgreSQL
npm install prisma
# Змінні оточення
npm install dotenv
# Захист HTTP-заголовків
npm install helmet
package.json та package-lock.json
package.json — "паспорт" вашого проєкту. У ньому записані всі залежності з діапазонами версій (наприклад, "express": "^4.18.0" — будь-яка 4.x від 4.18 і вище).
package-lock.json — фіксує точні версії кожного пакету та всіх його залежностей. Без нього два розробники можуть отримати різні версії бібліотек з однакового package.json — а це джерело багів типу "у мене працює, на сервері ні". Lock-файл завжди коммітиться в git.
npx — виконання без встановлення
npx — окремий інструмент який часто плутають з npm. Він запускає пакети без глобальної інсталяції. Замість npm install -g create-next-app && create-next-app — просто npx create-next-app. Пакет скачується, виконується і не залишається у системі.
Безпека NPM-пакетів
Supply chain attacks через NPM — реальна загроза. У 2024-2025 роках було кілька гучних випадків коли популярні пакети містили шкідливий код який крав токени або crypto-ключі. Окрім вразливостей у залежностях, не забувайте і про безпеку самого коду — SQL-ін'єкції залишаються однією з найпоширеніших атак на бекенд. Базові правила захисту NPM:
npm audit— перевіряє залежності на відомі вразливості. Запускайте після кожногоnpm install- Не встановлюйте пакети з <100 завантажень на тиждень без перевірки коду
- Завжди коммітьте package-lock.json — він фіксує integrity-хеші кожного пакету
npm ciзамістьnpm installна CI/CD — він ставить точно те що у lock-файлі, без "оновлення діапазонів"
Node.js vs NPM: різниця
Коротко: Node.js — це двигун. NPM — це магазин запчастин для цього двигуна.
| Компонент | Що робить | Аналогія |
|---|---|---|
| Node.js | Виконує JavaScript-код на сервері, працює з мережею, файлами, пам'яттю | Двигун автомобіля |
| NPM | Керує залежностями — встановлює, оновлює, видаляє бібліотеки | Магазин запчастин |
| npx | Запускає пакети одноразово без встановлення | Тест-драйв |
Встановлюючи Node.js, ви автоматично отримуєте і NPM, і npx. Перевірити версії:
node -v # v22.14.0 (LTS, рекомендована на травень 2026)
npm -v # 10.x
npx -v # 10.x (іде разом з npm)
Від нуля до робочого API за 5 хвилин
1. Встановлення через NVM
NVM (Node Version Manager) — правильний спосіб встановлення Node.js. Він дозволяє тримати кілька версій одночасно і перемикатись між ними, не ламаючи систему. І головне — не потрібен sudo для глобальних пакетів, що усуває цілий клас проблем з правами доступу.
# Встановити NVM
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
# Встановити Node.js 22 LTS
nvm install 22
# Перевірити
node -v # v22.14.0
npm -v # 10.x
2. Ініціалізація проєкту
# Створити package.json з дефолтними налаштуваннями
npm init -y
3. Перший сервер на Express
npm install express
Створіть app.js:
const express = require('express');
const app = express();
app.get('/', (req, res) => res.send('API працює'));
app.get('/health', (req, res) => {
res.json({ status: 'ok', uptime: process.uptime() });
});
app.listen(3000, () => console.log('Сервер запущено на порту 3000'));
Health-check ендпоінт — не декорація. Він потрібний для моніторингу: PM2, Nginx, або зовнішній сервіс перевіряють чи застосунок живий та скільки часу працює.
Продакшн: Nginx + PM2 + Node.js
Запустити node app.js у терміналі — це розробка. Для продакшну потрібен стек який забезпечує автозапуск, кластеризацію, reverse proxy та логування. Наш стандартний стек: Nginx перед Node.js як reverse proxy, PM2 як process manager.
PM2: process manager
# Глобальна інсталяція PM2
npm install -g pm2
Файл ecosystem.config.js — конфігурація яка визначає як запускати застосунок:
module.exports = {
apps: [{
name: "node-app",
script: "./dist/main.js",
instances: "max", // Використовує всі ядра CPU
exec_mode: "cluster", // Cluster mode для розподілу навантаження
env: {
NODE_ENV: "production",
PORT: 3000
},
error_file: "./logs/err.log",
out_file: "./logs/out.log",
log_date_format: "YYYY-MM-DD HH:mm:ss"
}]
}
Що дає PM2:
- Автоперезапуск — якщо процес впав через помилку, PM2 піднімає його за секунду
- Cluster mode — розподіляє навантаження на всі ядра CPU. На 4-ядерному VPS це 4 процеси замість одного
- Логування — stdout та stderr зберігаються у файли з датою
- Моніторинг —
pm2 monitпоказує CPU, RAM, Event Loop Latency у реальному часі
Так виглядає pm2 list на робочому продакшн-сервері:
А це деталі конкретного процесу через pm2 describe — версія Node.js 22.14.0, production environment, шлях до логів, uptime:
Nginx як reverse proxy
Nginx стоїть перед Node.js і приймає на себе SSL-термінацію, стиснення, кешування статичних файлів, та проксює запити до застосунку. Детальне порівняння Nginx та Apache — у нашій статті про Nginx vs Apache. Тут — мінімальний конфіг для Node.js:
server {
listen 80;
server_name api.yourdomain.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Рядки з Upgrade та Connection — підтримка WebSocket. Без них real-time функціональність (чати, нотифікації) працювати не буде. X-Real-IP передає справжню IP-адресу клієнта — без цього Node.js бачитиме всі запити як 127.0.0.1. Для захисту API від перевантажень варто також налаштувати DDoS-захист на рівні Nginx та мережі.
⚠️ Золоте правило Node.js: Не зберігайте стан (state) всередині процесу. Кеш у глобальній змінній, сесії у пам'яті, лічильники в об'єкті — все це зникає при рестарті, не шариться між інстансами у cluster mode, і з'їдає RAM без контролю. Виносьте стан у Redis, базу даних, або S3. Процес Node.js повинен бути stateless — тоді його можна перезапускати, масштабувати і оновлювати без наслідків.
Кейс: eCommerce API на NestJS
RESTful API для мобільного додатка та веб-вітрини. Стек: NestJS (TypeScript-фреймворк поверх Express), PostgreSQL, Redis. Хоча приклади у статті на чистому JavaScript — у реальних продакшн-проєктах ми рекомендуємо TypeScript. Типізація ловить помилки ще до запуску коду, а NestJS спроєктований під TypeScript з самого початку.
| Параметр | Значення |
|---|---|
| Навантаження | 450-600 RPS у пікові години |
| Активні користувачі | ~25 000 на добу |
| Конфігурація VPS | 4 vCPU, 8 GB RAM, NVMe диск |
| PM2 mode | Cluster (4 процеси) |
Проблеми які виявились:
Перша — витік пам'яті. Heap ріс щодня на 50-100 МБ і за тиждень процес з'їдав всю RAM. Причина: кешування результатів запитів до бази прямо у пам'яті Node.js процесу (об'єкт в глобальній змінній). При кожному унікальному запиті додавався новий запис, але ніколи не видалявся.
Рішення: винесли кешування у Redis із TTL (час життя) на кожен ключ. Пам'ять Node.js-процесу стабілізувалась на 150-200 МБ, Redis тримав кеш окремо і сам чистив застарілі записи.
Друга проблема — затримки при обробці зображень "на льоту" (resize thumbnails при завантаженні). Кожна операція блокувала Event Loop на 200-500 мс — і весь API для інших користувачів підвисав.
Рішення: винесли обробку зображень у чергу BullMQ з окремими worker-процесами. API приймає зображення, кидає задачу у чергу і повертає відповідь одразу. Worker у фоні обробляє зображення і зберігає результат. Event Loop вільний.
Топ-5 помилок при деплої Node.js
Ці помилки ми бачимо регулярно. Кожна з них рано чи пізно призводить до інциденту — питання тільки коли.
| Помилка | Чим загрожує | Рішення |
|---|---|---|
| Запуск від root | Якщо Node-застосунок зламають — зловмисник отримає повний контроль над VPS. Детальніше про безпеку серверу — у гайді по SSH Security | Створити окремого користувача nodeuser, запускати PM2 від нього |
Запуск через node app.js | При першій помилці процес падає і не піднімається. Ніхто не дізнається поки клієнт не поскаржиться | PM2 з автоперезапуском та pm2 startup для автозапуску при ребуті |
| node_modules у Git | Роздутий репозиторій (200+ МБ), помилки компіляції native-модулів (bcrypt) при деплої на Linux з Mac | .gitignore + npm ci на CI/CD |
| Секрети у коді | Токени і паролі до бази "зашиті" у JS-файли, потрапляють у git-історію. Навіть якщо видалити потім — вони залишаються в історії комітів | .env файл + dotenv + обов'язково .env у .gitignore |
| Блокування Event Loop | Генерація PDF, обробка зображень у головному потоці "вішає" весь API | Worker Threads або черги (BullMQ) для CPU-bound задач |
🚨 Окремо про .env: Файл .env з паролями до бази, API-ключами та токенами — одна з найчастіших причин зламу Node.js-проєктів. Розробник забуває додати .env у .gitignore, пушить у публічний репозиторій — і боти знаходять ці секрети за хвилини. Перевірте прямо зараз: git log --all --full-history -- .env — якщо файл коли-небудь був у git, секрети вже скомпрометовані і потрібно ротувати всі ключі.
Продуктивність: Node.js vs PHP vs Python
Внутрішні заміри на VPS (4 vCPU, 8 GB RAM, NVMe). Тестувався простий API-ендпоінт який робить SELECT до PostgreSQL та повертає JSON:
| Стек | RPS (Simple API) | Споживання RAM | Коментар |
|---|---|---|---|
| Node.js (Express) | 1 200 — 1 500 | ~100 МБ | Оптимально для I/O-bound задач |
| Python (Gunicorn) | 400 — 600 | Високе | Повільніше на синхронних запитах |
| PHP-FPM (Laravel) | 200 — 300 | Середнє | Потребує тонкого налаштування Opcache |
Node.js домінує на I/O-задачах — API, WebSocket, стрімінг. Але це не означає що PHP або Python "погані". Laravel виграє за швидкістю розробки для CRUD-додатків, Python незамінний для ML-задач. Вибір стеку визначається задачею, а не бенчмарками.
Коли Node.js — не найкращий вибір
Node.js однопотоковий за своєю природою. CPU-bound задачі — те де він програє:
- Важкі математичні обчислення, ML-inference — тут Python з NumPy або Go будуть швидше
- Обробка відео/аудіо — ffmpeg краще запускати як окремий процес, а не через Node.js binding
- Компресія великих файлів — zlib у Node.js блокує Event Loop на великих обсягах
Правило: якщо задача "чекає" (I/O) — Node.js ідеальний. Якщо задача "рахує" (CPU) — є кращі інструменти, або виносьте у Worker Threads.
Docker чи PM2: що обрати для деплою
Два підходи до запуску Node.js у продакшні. Обидва працюють, але для різних ситуацій:
| Критерій | PM2 (голий) | Docker |
|---|---|---|
| Складність налаштування | Простіше — один конфіг | Складніше — Dockerfile, compose |
| Продуктивність | Нативна, без overhead | Мінімальний overhead на мережу |
| Ізоляція | На рівні користувача ОС | Повна ізоляція файлової системи |
| CI/CD | Потребує скриптів | GitHub Actions / GitLab CI з коробки |
| Мікросервіси | Складно керувати | Docker Compose / Kubernetes |
PM2 — для монолітних проєктів де потрібна максимальна продуктивність з мінімальними накладними витратами. Простіше в обслуговуванні для невеликих команд.
Docker — для мікросервісних архітектур, складних залежностей (різні версії бібліотек для різних сервісів), або коли ви використовуєте CI/CD для автоматичного деплою.
А що щодо Deno та Bun?
Deno (від автора Node.js Раяна Дала) і Bun — дві альтернативні runtime-середовища які з'явились у 2020-2023 роках.
Deno виправляє архітектурні рішення Node.js які сам автор вважає помилками: вбудована підтримка TypeScript, модулі через URL замість node_modules, permissions за замовчуванням (процес не має доступу до файлової системи поки ви явно не дозволите). Deno 2.0 (2024) додав сумісність з NPM-пакетами, що зняло головний бар'єр до міграції.
Bun — зроблений на Zig замість C++, фокус на швидкості. Вбудований bundler, тест-раннер, і package manager. Порівняння швидкості встановлення залежностей — одна з найгарячіших тем серед розробників у 2026:
| Операція | npm | bun | Різниця |
|---|---|---|---|
| install (cold, без кешу) | ~35 с | ~3 с | ~10x швидше |
| install (з кешем) | ~15 с | ~1 с | ~15x швидше |
| Запуск TypeScript | Потребує tsc/tsx | Нативно | Без зайвих кроків |
Реальність на 2026 рік: Node.js досі займає 95%+ серверного JavaScript ринку. Deno та Bun — цікаві проєкти з окремими перевагами, але екосистема, стабільність, документація та кількість production-деплоїв у Node.js поки що недосяжні. Для нового проєкту — спробуйте Bun або Deno. Для production API з платними клієнтами — Node.js залишається безпечним вибором.
🚀 Розгортаєте Node.js проєкт?
VPS з підтримкою налаштування Nginx + PM2 — оптимальна основа для Node.js у продакшні.
💻 Cloud (VPS) Хостинг
- Від $19.95/міс — Починайте з малого, масштабуйте за потреби
- KVM віртуалізація — Гарантовані ресурси, ніякого overselling
- Node.js 22 LTS — Встановлюємо через NVM, налаштовуємо PM2
- 24/7 підтримка — <10 хв відповідь
🖥️ Виділені Сервери
- Від $90/міс — Виділений сервер для вашого проєкту
- Повний root-доступ — Будь-який стек без обмежень
- 99.9% uptime — SLA гарантія
- DDoS захист — Включено
- Безкоштовна міграція — Від старого хостингу
💬 Не впевнені який варіант вам необхідний?
💬 Напишіть нам і ми зі всім допоможемо!
Часті питання
- Яку версію Node.js обрати у 2026 році?
Node.js 22.x LTS — дефолтний вибір. Вона перейшла у статус Long Term Support восени 2025-го і підтримуватиметься до 2027. Для консервативних проєктів де важлива максимальна стабільність — 20.x LTS (підтримка до 2026). Встановлюйте через NVM — це дозволяє тримати кілька версій одночасно і перемикатись між ними.
- Чим NVM краще за системний Node.js?
Системний Node.js (через apt/yum) має три проблеми: одна версія на всю систему, потрібен sudo для глобальних пакетів (ризик безпеки), і оновлення залежить від репозиторію ОС який часто відстає на місяці. NVM вирішує все це — ви встановлюєте будь-яку версію у свій домашній каталог без root-доступу.
- Express, Fastify, NestJS — що обрати для API?
Express — найпростіший старт, найбільша екосистема middleware. Fastify — у 2-3 рази швидший за Express на бенчмарках, краща валідація через JSON Schema. NestJS — TypeScript-first фреймворк з архітектурою як у Angular (модулі, DI, декоратори), підходить для великих enterprise-проєктів. Для MVP — Express. Для high-load API — Fastify. Для команди з 5+ розробників — NestJS.
- Як моніторити Node.js у продакшні?
PM2 з вбудованим моніторингом — мінімум:
pm2 monitпоказує CPU, RAM, Event Loop Latency у реальному часі. Для серйозніших проєктів — Prometheus + Grafana (метрики), Sentry (помилки), або Datadog (все разом). Ключові метрики: Event Loop Latency (має бути <50 мс), Heap Usage (не повинен рости безкінечно), і Active Handles.
- Чи можна запускати Node.js без Nginx?
Технічно — так, Node.js може слухати порт 80/443 напряму. На практиці — не варто. Nginx набагато краще обробляє SSL-термінацію, стиснення (gzip/brotli), кешування статики, та захист від повільних з'єднань (slowloris). Node.js повинен займатись бізнес-логікою, а не обслуговуванням HTTP-з'єднань.
- Docker або PM2 — що краще для деплою?
Для монолітного проєкту з невеликою командою — PM2 простіше і швидше: один конфіг, нативна продуктивність, мінімум overhead. Для мікросервісів, складних залежностей, або при наявності CI/CD пайплайну (GitHub Actions, GitLab CI) — Docker. На VPS обидва варіанти працюють без обмежень — повний root-доступ дозволяє налаштувати будь-який стек.