Présentation

Node.js est un runtime JavaScript open source et multiplateforme qui permet d’exécuter du JavaScript hors du navigateur. Il est particulièrement utilisé pour construire des serveurs Web, API, outils en ligne de commande, scripts d’automatisation, services réseau et infrastructures de développement.

Le runtime repose sur V8, le moteur JavaScript également utilisé par Chromium. Node.js lui ajoute un ensemble important d’API système qui n’existent pas dans le langage JavaScript lui-même : accès aux fichiers, réseau TCP et HTTP, processus, système d’exploitation, chiffrement, streams, workers ou exécution de programmes externes.

Node.js est surtout connu pour son modèle asynchrone et événementiel. Plutôt que d’associer systématiquement un thread à chaque connexion réseau, il s’appuie sur une event loop et sur libuv pour orchestrer de nombreuses opérations concurrentes avec relativement peu de threads.

Cette architecture convient particulièrement aux applications effectuant beaucoup d’entrées/sorties : serveurs HTTP, API, WebSocket, accès réseau, fichiers ou communications avec des bases de données. Les calculs CPU très lourds demandent en revanche une attention particulière afin de ne pas bloquer l’event loop.

Node.js joue également un rôle central dans l’écosystème du développement Web moderne. De nombreux frameworks, bundlers, compilateurs, générateurs de sites et outils front-end s’exécutent eux-mêmes sur Node.js, même lorsque l’application finale doit fonctionner dans un navigateur.

Le runtime prend en charge les deux grands systèmes de modules de l’écosystème JavaScript : ECMAScript Modules — ESM, utilisant import et export, et CommonJS, utilisant historiquement require() et module.exports.

Son écosystème est fortement lié à npm, qui permet d’installer et publier des packages JavaScript. La distribution Current vérifiée, Node.js 26.8.2, est actuellement proposée avec npm 11.19.1.

Node.js dispose aujourd’hui également de nombreuses fonctions autrefois fournies uniquement par des bibliothèques externes : fetch(), WebSocket, Web Streams, test runner, gestion des permissions, support léger de TypeScript ou encore un module SQLite intégré en cours de stabilisation.

Lors de cette vérification, la dernière version publiée est Node.js 26.8.2 — Current. La dernière version LTS est Node.js 24.21.0 — Krypton. Pour les applications en production, le projet Node.js recommande d’utiliser une branche LTS encore prise en charge plutôt que la branche Current.

Fonctionnalités

Un runtime JavaScript construit autour de V8

Node.js utilise V8 pour parser, compiler et exécuter le code JavaScript.

Le moteur prend en charge les fonctionnalités modernes du langage ECMAScript et évolue à mesure que Node.js adopte de nouvelles versions de V8.

Node.js 26 utilise notamment V8 14.6 lors de son lancement de branche majeure et active par défaut certaines nouveautés du langage comme Temporal, la nouvelle API JavaScript destinée à mieux gérer dates, heures, fuseaux horaires et durées.

Le rôle de Node.js dépasse cependant celui du moteur JavaScript.

Il ajoute les API nécessaires pour transformer JavaScript en véritable environnement d’exécution système : fichiers, réseau, processus, chiffrement, threads, terminal et de nombreux autres services.

Event loop et modèle asynchrone

L’architecture Node.js repose principalement sur une event loop chargée d’exécuter le code JavaScript et de traiter les callbacks associés aux événements.

Les opérations longues d’entrée/sortie n’ont donc pas nécessairement besoin de bloquer cette boucle.

Node.js s’appuie notamment sur libuv, qui fournit l’event loop et une abstraction multiplateforme pour de nombreuses opérations système.

Certaines tâches utilisent également un Worker Pool, par exemple pour plusieurs opérations liées au système de fichiers ou à la cryptographie.

Cette architecture permet à un même processus Node.js de gérer un grand nombre de connexions simultanées lorsque chaque tâche JavaScript reste relativement courte.

Elle possède cependant une règle importante : un calcul CPU trop long exécuté directement dans l’event loop peut ralentir l’ensemble du serveur.

Le code doit donc éviter les traitements synchrones coûteux au milieu d’un serveur très sollicité ou déplacer les calculs importants vers des workers ou processus adaptés.

Serveurs HTTP et réseau intégrés

Node.js fournit directement les modules nécessaires pour créer des serveurs réseau.

Le module node:http permet de construire un serveur HTTP sans installer de framework externe.

node:https ajoute le support TLS pour HTTPS.

Le runtime comprend également des modules plus bas niveau pour TCP, UDP, DNS ou TLS.

Des frameworks comme Express, Fastify ou NestJS peuvent ensuite fournir une architecture plus confortable au-dessus de ces primitives.

Cette capacité à gérer le réseau directement explique en grande partie le succès historique de Node.js côté serveur.

fetch(), WebSocket et APIs proches du navigateur

Node.js a progressivement intégré plusieurs Web APIs également disponibles dans les navigateurs.

fetch() est aujourd’hui stable et permet d’effectuer des requêtes HTTP sans installer systématiquement une bibliothèque supplémentaire.

Son implémentation repose sur Undici, le client HTTP développé pour l’écosystème Node.js.

Le runtime fournit également des objets compatibles avec les APIs Web comme :

  • Headers ;
  • Request ;
  • Response ;
  • FormData ;
  • AbortController ;
  • URL ;
  • URLSearchParams ;
  • Web Streams.

WebSocket est lui aussi disponible nativement et stable depuis Node.js 22.4.

Ce rapprochement avec les standards Web facilite le partage de certaines parties du code entre navigateur et serveur, même si les deux environnements conservent de nombreuses différences.

Système de fichiers, chemins et informations système

Node.js peut accéder directement au système de fichiers avec node:fs.

Il permet notamment de :

  • lire et écrire des fichiers ;
  • créer ou supprimer des dossiers ;
  • récupérer des métadonnées ;
  • travailler avec des permissions ;
  • surveiller certains changements ;
  • créer des streams de lecture ou d’écriture.

La plupart des opérations importantes possèdent des variantes asynchrones.

node:fs/promises fournit une interface basée sur Promise et async/await.

node:path permet de manipuler les chemins sans dépendre manuellement des différences de séparateurs entre Windows et les systèmes Unix.

D’autres modules intégrés donnent accès au système d’exploitation, aux variables d’environnement, aux arguments du processus et aux informations d’exécution.

ECMAScript Modules et CommonJS

Node.js possède actuellement deux systèmes de modules principaux.

CommonJS constitue le modèle historique de Node.js, avec require() et module.exports.

ECMAScript Modules correspondent au standard JavaScript moderne avec import et export.

Un projet peut indiquer son format notamment avec :

  • l’extension .mjs pour ESM ;
  • l’extension .cjs pour CommonJS ;
  • le champ "type": "module" ou "type": "commonjs" dans package.json.

Node.js fournit aujourd’hui une interopérabilité importante entre les deux systèmes.

Les nouveaux projets peuvent donc utiliser directement les modules ES tout en continuant à exploiter une grande partie de l’écosystème historique CommonJS.

Cette coexistence peut néanmoins provoquer certains problèmes de configuration, en particulier dans les packages qui doivent fonctionner simultanément avec plusieurs outils ou versions de Node.js.

npm et gestion des packages

Node.js est étroitement associé à npm, le gestionnaire de packages historique de son écosystème.

Un projet Node.js utilise généralement un fichier package.json pour déclarer :

  • nom et version ;
  • dépendances ;
  • scripts ;
  • type de modules ;
  • contraintes de versions ;
  • métadonnées du package.

npm install récupère les dépendances nécessaires.

Les scripts npm peuvent ensuite automatiser tests, builds, linters, migrations ou autres commandes du projet.

L’écosystème npm contient un nombre extrêmement important de packages couvrant pratiquement tous les domaines du développement JavaScript.

Cette richesse constitue une force majeure de Node.js, mais implique également de surveiller les dépendances, leurs licences, leur maintenance et leurs vulnérabilités.

Exécution native légère de TypeScript

Node.js possède désormais un support natif de TypeScript par type stripping.

Cette fonction est stable dans les versions récentes et activée par défaut.

Node.js peut exécuter directement des fichiers TypeScript utilisant uniquement une syntaxe de types pouvant être supprimée sans générer de nouveau JavaScript.

Le runtime remplace essentiellement les annotations de types par des espaces puis exécute le JavaScript restant.

Il est important de comprendre les limites de cette fonction :

  • Node.js ne vérifie pas les types ;
  • tsconfig.json est ignoré par ce mode ;
  • les alias paths de TypeScript ne sont pas transformés ;
  • les fichiers .tsx ne sont pas pris en charge ;
  • certaines constructions nécessitant une transformation JavaScript, comme les enum, ne fonctionnent pas avec le simple type stripping ;
  • les imports de types doivent utiliser correctement import type.

Pour bénéficier de toutes les fonctionnalités TypeScript, de la vérification des types et de la configuration tsconfig, il reste préférable d’utiliser le compilateur TypeScript ou un outil adapté comme tsx.

Le support intégré de Node.js vise donc surtout à exécuter simplement du TypeScript léger, pas à remplacer l’ensemble de la toolchain TypeScript.

Streams pour traiter les données progressivement

Les streams constituent une primitive centrale de Node.js.

Au lieu de charger intégralement un fichier ou une réponse réseau en mémoire, une application peut traiter les données progressivement.

Node.js distingue principalement :

  • Readable ;
  • Writable ;
  • Duplex ;
  • Transform.

Un fichier lu depuis le disque, une requête HTTP, une réponse serveur, un socket TCP ou la sortie standard peuvent être représentés sous forme de streams.

Cette architecture est particulièrement utile pour :

  • gros fichiers ;
  • uploads ;
  • téléchargements ;
  • compression ;
  • proxy réseau ;
  • transformation de données.

stream.pipeline() facilite l’enchaînement de plusieurs étapes tout en gérant correctement erreurs et fermeture des streams.

Node.js prend également en charge l’interopérabilité avec les Web Streams utilisés par les standards Web modernes.

Worker Threads pour les calculs CPU

Le module node:worker_threads permet d’exécuter du JavaScript en parallèle dans plusieurs threads.

Les workers sont principalement utiles pour les opérations CPU-intensive.

Ils peuvent partager certaines données grâce à SharedArrayBuffer ou transférer des ArrayBuffer.

Pour les opérations d’entrée/sortie classiques, les APIs asynchrones natives de Node.js sont généralement plus adaptées que la création de workers.

L’usage typique consiste donc à réserver l’event loop aux opérations réseau et à déplacer certains calculs coûteux vers un pool de Worker Threads.

Processus enfants et exécution parallèle

Node.js peut également lancer d’autres processus avec node:child_process.

Cette API permet notamment :

  • d’exécuter une commande système ;
  • de lancer un programme externe ;
  • de créer un processus Node.js enfant ;
  • d’échanger des messages entre processus.

Les processus offrent une isolation plus forte que les Worker Threads mais consomment généralement davantage de ressources.

Le module historique cluster permet aussi d’utiliser plusieurs processus Node.js partageant des ports serveur afin d’exploiter plusieurs cœurs CPU.

Selon l’architecture moderne choisie, cette répartition peut également être assurée par un orchestrateur, un conteneur ou un load balancer externe.

Test runner intégré

Node.js dispose de son propre test runner avec le module node:test.

Il est stable depuis Node.js 20.

Il permet d’écrire et exécuter des tests sans installer obligatoirement Jest, Mocha ou une autre solution externe.

Le runner prend en charge notamment :

  • tests synchrones et asynchrones ;
  • describe() et it() ;
  • hooks de préparation et nettoyage ;
  • sous-tests ;
  • tests skipped ou TODO ;
  • mocks ;
  • filtrage ;
  • exécution en ligne de commande.

La commande node --test peut automatiquement rechercher et exécuter les fichiers correspondant aux conventions de tests reconnues.

Les bibliothèques spécialisées restent utiles pour certains projets, mais Node.js possède désormais une base de testing directement intégrée au runtime.

Permission Model

Node.js dispose d’un Permission Model stable permettant de limiter certaines capacités du processus.

Lorsqu’il est activé avec --permission, l’accès à différentes ressources peut être refusé par défaut puis autorisé explicitement.

Les restrictions peuvent notamment concerner :

  • lecture et écriture de fichiers ;
  • réseau ;
  • processus enfants ;
  • Worker Threads ;
  • addons natifs ;
  • inspector ;
  • WASI ;
  • FFI.

Il existe également un mode audit qui signale les violations sans les bloquer.

Le projet Node.js précise toutefois clairement que ce mécanisme constitue une ceinture de sécurité pour du code de confiance, et non une sandbox destinée à neutraliser du code volontairement malveillant.

Le Permission Model doit donc compléter une architecture de sécurité et non la remplacer.

SQLite directement dans Node.js

Node.js intègre désormais le module node:sqlite.

Il permet d’utiliser une base SQLite directement depuis le runtime sans installer obligatoirement un binding externe.

L’API permet notamment d’ouvrir une base, préparer des requêtes et manipuler les types courants SQLite.

Dans Node.js 26.8.2, ce module est encore classé Release Candidate et n’a donc pas encore atteint le niveau stable complet des APIs historiques.

Cette fonction montre néanmoins l’évolution de Node.js vers un runtime proposant davantage de briques applicatives directement intégrées.

Cryptographie et sécurité

Le module node:crypto fournit des fonctions de cryptographie reposant notamment sur OpenSSL.

Il permet de travailler avec :

  • hashes ;
  • HMAC ;
  • chiffrement ;
  • déchiffrement ;
  • signatures ;
  • génération de clés ;
  • dérivation de clés ;
  • certificats ;
  • nombres aléatoires sécurisés.

Node.js expose également une implémentation de Web Crypto API pour mieux s’aligner sur les standards Web.

Ces outils sont particulièrement utiles pour authentification, tokens, intégrité des données et communications sécurisées.

Les primitives cryptographiques doivent néanmoins être utilisées avec des algorithmes et paramètres adaptés : disposer d’une API crypto ne garantit pas qu’une implémentation applicative soit sûre.

Addons natifs et Node-API

Node.js peut être étendu avec du code natif.

Node-API fournit une interface destinée à construire des addons natifs tout en réduisant la dépendance directe à une version particulière du moteur V8.

Cette approche est utilisée par certaines bibliothèques qui ont besoin de performances natives, d’accéder à une bibliothèque C/C++ existante ou d’interagir avec des fonctions système non disponibles directement en JavaScript.

Le développement d’addons natifs reste plus complexe qu’un package JavaScript classique et demande souvent une chaîne de compilation spécifique selon le système.

Pour de nombreux usages, WebAssembly constitue également une autre manière d’intégrer du code compilé à une application Node.js.

Outils de diagnostic et performances

Node.js fournit plusieurs outils intégrés pour examiner le fonctionnement d’une application.

L’inspector permet notamment de connecter les outils de développement compatibles avec le protocole DevTools.

Le runtime fournit aussi des APIs pour :

  • performance timing ;
  • heap et mémoire ;
  • diagnostics channels ;
  • rapports de diagnostic ;
  • tracing ;
  • profiling V8.

Ces fonctions deviennent importantes lorsqu’une application serveur présente une fuite mémoire, une consommation CPU excessive ou des latences difficiles à reproduire.

Versions Current et LTS

Node.js distingue plusieurs phases de publication.

La branche Current reçoit les nouveautés les plus récentes.

Les versions LTS — Long-Term Support sont destinées aux applications nécessitant davantage de stabilité et de maintenance.

Au 13 septembre 2026 :

Branche Statut Version vérifiée
Node.js 26 Current 26.8.2
Node.js 24 — Krypton LTS 24.21.0
Node.js 22 — Jod LTS 22.23.2

Node.js 26 doit entrer en LTS en octobre 2026.

Le projet recommande d’utiliser en production une version Active LTS ou Maintenance LTS encore prise en charge.

Les versions EOL ne reçoivent plus la maintenance publique normale et doivent être mises à niveau.

Le calendrier évoluera également à partir de Node.js 27 avec un nouveau rythme annuel de versions majeures.

Cas d’usage

Construire une API Web

Node.js peut recevoir des requêtes HTTP, interroger une base de données puis retourner du JSON à un client Web ou mobile.

Il peut être utilisé directement avec node:http, mais la majorité des projets adoptent un framework comme Express, Fastify ou NestJS afin de structurer routes, middlewares et validation.

Son modèle asynchrone convient particulièrement aux API effectuant beaucoup d’opérations réseau ou d’accès aux données.

Une même équipe peut en outre utiliser JavaScript ou TypeScript à la fois côté navigateur et côté serveur.

Créer un service temps réel

Node.js est bien adapté aux applications conservant de nombreuses connexions simultanées.

Chat, notifications, collaboration, dashboards live ou jeux réseau peuvent utiliser WebSocket ou d’autres protocoles temps réel.

Le runtime peut gérer efficacement de nombreuses connexions lorsque chaque événement demande relativement peu de calcul CPU.

Les opérations lourdes doivent être séparées afin d’éviter qu’elles bloquent l’event loop.

Construire des outils en ligne de commande

Node.js est largement utilisé pour développer des CLI.

Un outil peut lire des arguments, parcourir des fichiers, exécuter des commandes, télécharger des ressources ou transformer du contenu.

Une grande partie des outils du développement Web — linters, bundlers, générateurs ou scripts de build — repose historiquement sur cette possibilité.

Un package peut ensuite exposer une commande installable avec npm.

Automatiser des workflows de développement

Un script Node.js peut :

  • générer des fichiers ;
  • traiter du JSON ou YAML ;
  • redimensionner ou convertir des ressources via des bibliothèques ;
  • préparer un build ;
  • analyser du code ;
  • communiquer avec une API ;
  • lancer plusieurs outils externes.

JavaScript devient ainsi un langage d’automatisation utilisable sur Windows, macOS et Linux sans dépendre d’un shell unique.

Faire fonctionner un framework Web côté serveur

De nombreux frameworks front-end ou full-stack utilisent Node.js pendant le développement et/ou en production.

Le runtime peut gérer :

  • rendu serveur ;
  • génération statique ;
  • API internes ;
  • build ;
  • middleware ;
  • optimisation d’assets.

Des frameworks comme Next.js, Nuxt et de nombreuses autres plateformes JavaScript utilisent Node.js comme environnement d’exécution ou comme l’un de leurs runtimes possibles.

Traiter des fichiers et flux de données

Les streams permettent à Node.js de traiter de gros volumes de données sans charger systématiquement l’ensemble en mémoire.

Une application peut lire un fichier, le décompresser, le transformer puis l’envoyer vers un serveur ou un autre fichier sous forme de pipeline.

Cette architecture est adaptée aux imports, exports, proxies, traitements médias ou outils de données.

Pour les traitements CPU très lourds, elle peut être combinée avec Worker Threads ou des processus spécialisés.

Conclusion

Node.js a profondément transformé l’écosystème JavaScript en permettant d’utiliser le même langage bien au-delà du navigateur.

Son principal intérêt ne réside pas seulement dans la possibilité d’exécuter JavaScript sur un serveur. Le runtime fournit désormais un environnement système très complet avec réseau, fichiers, streams, processus, cryptographie, tests, workers et nombreuses APIs compatibles avec les standards Web.

Son architecture événementielle reste particulièrement adaptée aux applications qui passent une grande partie de leur temps à attendre des entrées/sorties : requêtes HTTP, bases de données, fichiers ou connexions réseau.

Cette architecture possède cependant ses propres contraintes. Une opération JavaScript CPU-intensive exécutée trop longtemps sur le thread principal peut bloquer l’event loop et dégrader toutes les requêtes traitées par le processus. Worker Threads, processus séparés ou services spécialisés deviennent alors nécessaires.

La coexistence d’ESM et CommonJS constitue également un héritage important de l’écosystème. Node.js prend désormais correctement en charge les modules standards JavaScript, mais les projets utilisant d’anciennes dépendances peuvent encore rencontrer des différences entre les deux modèles.

Le runtime continue parallèlement à absorber des fonctions autrefois externes. fetch(), WebSocket, Web Streams, test runner, Permission Model et support direct de certains fichiers TypeScript réduisent progressivement le nombre de dépendances nécessaires pour démarrer un projet.

Le support natif de TypeScript est cependant volontairement limité. Node.js supprime les annotations de types mais n’effectue pas leur vérification et n’interprète pas l’ensemble de tsconfig.json. Une vraie toolchain TypeScript reste donc nécessaire pour les applications qui veulent bénéficier pleinement du langage.

Node.js 26 poursuit cette évolution avec V8 14.6, Temporal activé par défaut et différentes améliorations du runtime. Au 13 septembre 2026, cette branche reste toutefois Current, tandis que Node.js 24.21.0 constitue le dernier LTS recommandé pour les environnements privilégiant la stabilité.

Le cycle LTS demeure ainsi une partie essentielle de l’utilisation professionnelle de Node.js. Utiliser une branche EOL peut exposer une application à des problèmes de sécurité et de compatibilité non corrigés publiquement.

Pour créer des API, services temps réel, outils CLI, scripts d’automatisation ou infrastructures Web entièrement basées sur JavaScript ou TypeScript, Node.js reste l’un des runtimes les plus importants et les plus polyvalents de l’écosystème logiciel moderne.

Points d’attention

  • La dernière version publiée vérifiée est Node.js 26.8.2 — Current, sortie le 9 septembre 2026.

  • La dernière version LTS vérifiée est Node.js 24.21.0 — Krypton.

  • Node.js 26 doit passer en LTS en octobre 2026. Avant cette transition, les applications de production devraient privilégier une branche LTS prise en charge.

  • Node.js est gratuit et open source sous licence MIT. Certaines dépendances tierces incluses dans le projet utilisent leurs propres licences open source.

  • Node.js utilise le moteur JavaScript V8, mais ajoute ses propres APIs système autour du langage ECMAScript.

  • Le code JavaScript principal est exécuté par l’event loop, mais Node.js utilise également un Worker Pool et peut créer Worker Threads ou processus supplémentaires.

  • Les traitements CPU longs peuvent bloquer l’event loop. Les tâches de calcul importantes doivent être découpées ou déplacées vers des workers ou processus adaptés.

  • Node.js prend en charge ESM et CommonJS. Leur interopérabilité s’est fortement améliorée, mais leur coexistence peut encore demander une configuration précise.

  • fetch() et WebSocket sont disponibles directement dans les versions modernes de Node.js, ce qui réduit le besoin de certaines dépendances externes.

  • Le support TypeScript intégré est un type stripping léger et stable, pas un compilateur TypeScript complet.

  • Node.js ne vérifie pas les types pendant son exécution native des fichiers .ts, ignore tsconfig.json pour ce mécanisme et ne prend pas en charge .tsx.

  • Certaines syntaxes TypeScript nécessitant une transformation en JavaScript, comme les enum, ne fonctionnent pas avec le simple type stripping natif.

  • node:test fournit un test runner intégré stable, mais Jest, Vitest, Mocha et d’autres solutions restent utilisables lorsque leurs fonctions sont mieux adaptées au projet.

  • Le Permission Model est stable, mais le projet précise qu’il ne constitue pas une sandbox contre du code malveillant.

  • node:sqlite est intégré au runtime mais reste classé Release Candidate dans Node.js 26.8.2, et doit donc être évalué en fonction des exigences de stabilité du projet.

  • Worker Threads sont surtout destinés aux tâches CPU-intensive. Pour les opérations d’entrée/sortie classiques, les APIs asynchrones natives sont généralement plus efficaces.

  • npm constitue une partie centrale de l’écosystème Node.js, mais les dépendances doivent être surveillées en matière de maintenance, sécurité, licences et compatibilité.

  • Les versions Node.js EOL ne reçoivent plus la maintenance publique normale. Les applications doivent suivre le calendrier LTS et planifier leurs mises à jour.

  • À partir de Node.js 27, le calendrier de publication évolue vers un cycle annuel de versions majeures, avec une transition LTS prévue pour chaque branche après les différentes phases de publication.

  • Node.js est multiplateforme, avec distributions officielles notamment pour Windows, macOS et Linux, et convient particulièrement aux serveurs et environnements self-hosted.