فاضل 8 أيام على 30 أبريل 2026. Node.js 20 هيخلص دعم رسميًا يوم الخميس الجاي. اللي بعدها مفيش security patches ولا bug fixes ولا حتى دعم runtime من AWS Lambda. هنا بالظبط خطة ترحيل شغّالة في الوقت ده لـ Node.js 22 LTS بدون downtime.
Node.js 20 EOL: المهلة الحقيقية وأول قرار لازم تاخده
المشكلة باختصار
Node.js 20 دخل Active LTS في أكتوبر 2023 وكان مفترض يفضل مدعوم لحد أبريل 2026. الميعاد وصل. بعد يوم 30 أبريل: أي CVE جديدة في V8 أو OpenSSL مش هتتسد في 20. AWS Lambda بتوقف تحديثات الأمن على الـ runtime بتاع nodejs20.x. GitHub Actions بدأت deprecation من سبتمبر 2025، وبعد نهاية الشهر الـ actions اللي بتعتمد على Node 20 هتبدأ تتعطّل تدريجيًا.
ليه ده مش مجرد نسخة بتعدّي
فيه كذا تفصيلة مخفية بتخلّي ترحيل 20 إلى 22 مش drop-in زي اللي كتير فاكرين. ركّز على الثلاثة دول بالتحديد:
- OpenSSL 3.5 بيرفض أي مفتاح RSA/DSA/DH أقل من 2048-bit افتراضيًا. لو عندك certs قديمة أو private keys بتتحمّل من vault بطول 1024-bit، الخدمة هترمي
ERR_SSL_EE_KEY_TOO_SMALLمن أول دقيقة بعد الترقية. - مكتبة punycode اتشالت من الـ core. أي كود قديم بيعمل
require('punycode')هيرجعMODULE_NOT_FOUND. الحل: ثبّتpunycodeمن npm كـ dependency خارجية. - V8 13.x بيفعّل
Float16ArrayوRegExp.escape()افتراضيًا. مش هتكسر حاجة، لكن لو عندك polyfills قديمة بتشيك على وجود التوابع، هتلاقي branches ميّتة في الكود بتاعك.
مثال بسيط للمبتدئ
تخيّل عندك خدمة Node 20 بتعمل HTTPS request لسيرفر داخلي شغّال self-signed cert من 2019. التاريخ ده معناه غالبًا المفتاح 1024-bit. بعد الترقية لـ 22 هيحصل الآتي فورًا:
node:internal/tls:443
throw new Error('unable to verify the first certificate');
^
Error [ERR_SSL_EE_KEY_TOO_SMALL]: EE key too small
at TLSSocket.onConnectSecure (node:_tls_wrap:1670:34)
الحل مش NODE_TLS_REJECT_UNAUTHORIZED=0، ده بيطفي الـ TLS كله ويفتح الباب لـ MITM. الحل الصحيح: ولّد cert جديد 2048-bit أو أعلى، أو ارفع security level للخدمة المقابلة. ولو مجبور على توافق مؤقت، استخدم --tls-min-v1.2 --security-revert=CVE-XXXX ليوم واحد فقط لحد ما تعدّل الـ cert.
المفهوم علميًا
الـ LTS (Long-Term Support) في Node.js بيعني نسخة بتدخل Active Maintenance لمدة 18 شهر، بعدها تدخل Maintenance بس لمدة 12 شهر تاني، وبعدها EOL. الدورة كلها 30 شهر من أول Active LTS release. الأرقام الزوجية بس (18, 20, 22, 24) هي اللي بتدخل LTS. الفردية (21, 23, 25) عمرها 6 شهور بس وبتتقطع. EOL مش تحذير، ده انقطاع فعلي لـ security backports من مشروع Node.js نفسه.
خطة الـ 8 أيام
الخطة دي مبنية على فرضية إن عندك مشروع إنتاجي واحد لحد 5 خدمات، وفريق 1 إلى 3 مطوّرين. لو الحجم أكبر، ابدأ بأعلى خدمة في الـ traffic وسيب الباقي لـ sprint ثاني.
- يوم 1 (النهارده): شغّل
npx is-my-node-vulnerableوnpm auditعلى كل مشروع. سجّل النسخ الحالية وأي deprecation warnings في issue tracker واحد. - يوم 2–3: جهّز staging على Node 22.14 LTS. شغّل الـ test suite كاملة. ركّز على مكتبات الـ native bindings (
bcrypt,sharp,better-sqlite3,canvas) لأنها أكتر حاجة بتكسر. - يوم 4: اختبر certs و TLS endpoints. أي حاجة بتتكلم مع LDAP قديم أو vault بمفاتيح 1024-bit هتكشف نفسها هنا.
- يوم 5–6: canary deploy لخدمة واحدة بـ 10% traffic. راقب CPU و memory و P95 latency لمدة 24 ساعة كاملة.
- يوم 7: ارفع لـ 100% على الخدمة الأولى، وابدأ الباقي بالتوازي على staging.
- يوم 8: شيل الـ rollback path، امسح images Node 20 من الـ registry، وحدّث CI pipelines.
أمر تشخيص سريع قبل الترحيل
# افحص كل مشاريعك مرة واحدة
find . -name "package.json" -not -path "*/node_modules/*" \
| xargs grep -l '"node"' \
| xargs -I {} sh -c 'echo "=== {} ==="; grep -A1 "\"engines\"" {}'
# افحص الـ lockfile لمشاكل native modules
npm ls --all 2>&1 | grep -iE "deprecated|native|gyp"
# اتأكد إن مفيش dependency على punycode المدمج
grep -rn "require('punycode')\|from 'punycode'" src/ --include="*.js" --include="*.ts"
# نسخة Docker للفحص على بيئة نظيفة
docker run --rm -v "$PWD":/app -w /app node:22-alpine npm test
22 LTS ولا 24؟ الـ trade-off الحقيقي
Node 22 دخل Active LTS في أكتوبر 2024 وهيفضل مدعوم لحد أبريل 2027. Node 24 طلع أكتوبر 2025 وهيفضل مدعوم لحد أبريل 2028.
- روح لـ 22 لو: عندك production حرج وdependencies مجمّدة. بتكسب استقرار ومكتبات متوافقة 100%. بتخسر إنك هترحّل تاني بعد سنة. V8 12.4 مستقر جدًا.
- روح لـ 24 لو: فريقك رشيق ومكتباتك بتتحدّث بانتظام. بتكسب
node --runبدلnpm run(3× أسرع لاستدعاء السكربت)، وfetchstable بدون flag، وpermission model محسّن. بتخسر: بعض native addons لسه بترّبع.
الأرقام من benchmark Fastify الرسمي: فرق الـ HTTP throughput بين 22 و24 حوالي 12% لصالح 24. مش كافي يبرّر الترحيل لو التطبيق مش I/O bound أصلاً. قاعدة سريعة: لو الـ bottleneck عندك هو DB أو external API، ابق على 22.
متى لا تترقّى الآن
الترقية مش إجبارية لكل سياق. ابق على Node 20 بشكل مؤقت بس لو واحدة من دول تنطبق عليك:
- عندك عقد extended support من HeroDevs أو TuxCare. بيقدّموا security patches لـ 20 لمدة 4 سنين إضافية بمقابل مادي واضح.
- التطبيق بيدور داخل شبكة معزولة (air-gapped) والـ attack surface محدودة جدًا.
- فيه dependency حرجة مش داعمة 22 لسه. نادر جدًا في 2026، لكن لسه فيه enterprise SDKs معيّنة بتتأخر.
الحسبة في الحالات دي: تكلفة الدعم الممتد حوالي $500 إلى $3000 لكل خدمة سنويًا، مقابل تكلفة الترحيل الفورية. لو الترحيل بياخد من فريقك أسبوعين عمل، الـ extended support أرخص. لو بياخد يومين، أكمل الترحيل.
الخطوة التالية
افتح المشروع الإنتاجي الأعلى traffic عندك، شغّل npx is-my-node-vulnerable، وأضف ملف .nvmrc محتواه 22 في الـ root. الخطوة دي بتاخد 10 دقايق وبتحل 80% من المشاكل المحتملة قبل ما توصل للـ deploy. بعدها، افتح PR صغير بيحدّث engines في package.json لـ "node": ">=22.0.0" علشان CI يمسك أي انحراف تلقائيًا.
مصادر
- Node.js Official Releases & EOL Schedule — nodejs.org/en/about/previous-releases
- HeroDevs — Node.js v20 Is Reaching End of Life (2026).
- CloudQuery Blog — AWS Lambda Node.js 20 EOL: Upgrade to Node.js 22.
- OpenSSL 3.5 CHANGES.md — Default security level raised to 2, keys < 2048-bit rejected.
- endoflife.date/nodejs — جدول EOL المحدّث لكل نسخ Node.
- GitHub Changelog — Deprecation of Node 20 on GitHub Actions runners (سبتمبر 2025).
- DEV Community — Node.js 20 End of Life Migration Playbook for April 30, 2026.
- Fastify Benchmarks — HTTP throughput comparison across Node LTS versions.