21 points par GN⁺ 2025-08-18 | 7 commentaires | Partager sur WhatsApp
  • Node.js a été amélioré pour pouvoir exécuter directement des fichiers TypeScript
  • Il est désormais possible d’exécuter des fichiers .ts directement, sans configuration supplémentaire ni transpilation
  • Les développeurs peuvent ainsi gagner en efficacité sans tsconfig.json ni installation d’un bundler séparé
  • Cette fonctionnalité est officiellement intégrée à partir de Node.js v22.18.0 (LTS)
  • On peut s’attendre à un estompage de la frontière entre le développement JavaScript et TypeScript

Prise en charge de l’exécution directe de TypeScript dans Node.js

  • Dans sa récente version v22.18.0 (LTS), Node.js a introduit une fonction permettant d’exécuter directement des fichiers TypeScript (.ts) sans configuration ni outil supplémentaire
  • Jusqu’à présent, l’exécution de code TypeScript nécessitait des transpileurs externes ou des bundlers comme ts-node, esbuild ou Babel, mais Node.js reconnaît et exécute désormais lui-même le code TypeScript sans ces outils
  • Grâce à cette fonctionnalité, les développeurs peuvent exécuter directement des fichiers .ts dans Node.js sans fichier de configuration tsconfig.json ni bibliothèque additionnelle
  • La productivité et le confort de développement augmentent nettement pour le prototypage, le développement expérimental ou l’exécution de scripts
  • On attend aussi un renforcement de l’interopérabilité entre les projets JavaScript et TypeScript, ainsi qu’une baisse de la barrière d’entrée pour les nouveaux développeurs

Autres changements notables

  • esm : implémentation de import.meta.main
  • fs : amélioration de la gestion des événements fs basée sur AsyncIterator
  • permission : prise en charge de la transmission des flags du modèle d’autorisations lors de l’exécution de sous-processus
  • sqlite : ajout de l’option readBigInts
  • src/permission : prise en charge de permission.has(addon)
  • url : ajout de l’API fileURLToPathBuffer
  • watch : ajout du flag --watch-kill-signal
  • worker : amélioration de l’objet Worker en tant qu’async disposable

Mises à jour liées aux commits et à la documentation

  • Suppression de code inutile, nettoyage de l’environnement de build et de la toolchain, avec mise à niveau vers npm 10.9.3
  • Correction d’indicateurs de stabilité détaillés et de numéros RFC dans la documentation, notamment globals.md, child_process.md et http2
  • Ajout de nombreux tests et intégration de corrections de bugs

Fichiers de distribution

  • Fichiers d’installation et binaires fournis pour Windows, macOS (Intel/Apple Silicon) et Linux (x64, ARM, PPC, s390x, AIX)
  • Le code source et l’ensemble des fichiers de release peuvent être téléchargés depuis la page officielle de distribution de Node.js
  • La documentation API a été mise à jour sur la base de la v22.18.0

7 commentaires

 
aliveornot 2025-08-19

Ah, ça fait vraiment du bien... J’espère que ça s’imposera vite.

 
tested 2025-08-18

Ça peut convenir pour exécuter de petits scripts, mais pour un projet en production il y a tellement de limitations que ça ne semble pas très utile.

Il faut aussi ajuster correctement les extensions et les chemins à cause des erreurs ERR_MODULE_NOT_FOUND / ERR_UNSUPPORTED_DIR_IMPORT,
et on ne peut pas utiliser des fonctionnalités comme NestJS qui nécessitent la prise en charge de la compilation TypeScript avec le paramètre emitDecoratorMetadata, donc...

 
kimjeongwonn 2025-08-18

Est-ce que --experimental-strip-types est appliqué par défaut ?

 
click 2025-08-18

De toute façon, je n’utilise pas les enum, donc de mon point de vue, le simple fait de supprimer les types suffit déjà pour que ça fonctionne très bien.

 
crawler 2025-08-18

Ça va devenir super pratique !

 
honglu 2025-08-18

Impossible de retenir mon gros pouce levé.

Je trouvais déjà ça très bien avec le flag --no-experimental-strip-types.

Ça a l’air encore mieux, d’ailleurs.

 
GN⁺ 2025-08-18
Avis Hacker News
  • Avec node:test dans Node.js, j’ai l’impression que Node.js est désormais un choix par défaut convaincant dans la plupart des cas. L’exécution via tsx avait déjà apporté un gros gain de confort, mais ce n’était pas encore complètement abouti. Les assertions de types à l’exécution en périphérie sont désormais largement couvertes par des outils comme zod, ts-rest et trpc, et aujourd’hui le développement full-stack en Typescript est vraiment devenu simple
    • C’est vrai. En 2025, l’écosystème Node est enfin devenu utilisable avec la configuration par défaut. Les modules ESM fonctionnent simplement, côté Node comme côté Typescript, Node peut exécuter directement des fichiers .ts, et il intègre un runner de tests de bon niveau (avec prise en charge de --watch). Les packages intégrés s’améliorent aussi. Avec node:fs/promises, par exemple, les boucles de travail asynchrones sont bien plus simples grâce au top-level await. Il a fallu du temps pour amener tout le monde à une approche réaliste, mais c’est enfin devenu très agréable
    • Je suis totalement pour la prise en charge directe de Typescript dans Node. Vitest simplifie beaucoup de choses aujourd’hui, mais j’ai passé énormément de temps sur la configuration des environnements de test pour les fichiers .ts. Je pense que trpc et ts-rest répondent à des problèmes complètement différents. On peut utiliser les deux, mais en production j’évite trpc, parce que je ne peux pas vraiment maîtriser moi-même les URL d’API ni gérer et déprécier proprement les anciennes URL. Pour ts-rest aussi, je préfère généralement partager directement zod et les types pour gérer moi-même les paires requête/réponse d’API. Et à chaque fois, ça m’agace que trpc soit clairement un outil RPC alors qu’il a -rest dans son nom
    • Je vais suivre avec intérêt si Sveltr finira par rebasculer sa base de code vers Typescript
    • Je me demande si ça exécute aussi les fichiers tsx. Même si on supprime les types, le JSX doit quand même être transformé en JavaScript, donc je me pose la question
    • Je suis récemment passé à Python. Je suis bien plus satisfait, parce que tout est intégré et que je n’ai plus à déboguer tout un tas de problèmes bizarres d’un système inachevé
  • J’ai été très impressionné par les progrès de Node ces dernières années. C’est bien que deno et bun aient poussé Node à se remettre au travail de manière ciblée et utile. Il y avait eu une longue période de stagnation
    • Je me demande quelles améliorations récentes Node a eues. La dernière que j’avais trouvée vraiment importante, c’était la prise en charge officielle de import/export (je ne sais même pas s’il faut encore le hack .mjs). J’étais un peu sorti de l’écosystème, donc j’aimerais savoir ce qui a changé depuis
    • Je ne suis pas sûr que ce soit vraiment le cas. Si je regarde les projets auxquels j’ai participé, deno ou bun n’étaient absolument pas nécessaires. En pratique, ce qui compte vraiment, ce sont les versions LTS de Node, et même les projets récents utilisent encore Node 20
  • Je trouve dommage que Typescript ne soit pas accepté dans node_modules (voir : documentation officielle node.js). Du coup, je me demande ce qu’il en est des dépendances de projet. J’ai écrit une bibliothèque de modèles de données en Typescript, et j’aimerais l’importer telle quelle dans mon app. Je me demande si cette règle ne s’applique qu’aux packages npm, ou à toutes les dépendances. Il y a une opportunité ici. J’ai créé un runtime basé sur golang pour exécuter typescript (plus précisément JS en général), et sobek utilisé par l’équipe Grafana pourrait probablement faire la même chose avec une simple fonction de type stripping. J’ai vraiment le sentiment que si un seul runtime adoptait complètement Typescript comme choix par défaut, ce serait une vraie révolution pour Node.js. Pas besoin de transpileur, ni de typescript-go, ni de rust (même si rust reste sympa😉), juste un bon parseur avec un système capable de suivre les source maps et les types en mode debug. Quoi qu’il en soit, reconnaissance et merci à l’équipe Node et à tous les contributeurs. On a l’impression que tout le monde suit derrière Node, qui fait office de standard. L’API d’embarquement est aussi simple et propre à utiliser, ce qui est pratique pour produire des exécutables autonomes
    • J’avais laissé le même commentaire (référence). Il y a le passage « pour décourager la publication sur npm de packages écrits en Typescript », et j’ai essayé aussi avec un package privé, mais ça n’a pas fonctionné, Node ne tient même pas compte du champ private
    • Je pense qu’un package devrait obligatoirement être compilé et publié en JavaScript avant d’être distribué sur npm. Je ne vois aucune raison de publier du TypeScript brut sur npm
  • Issue liée Je trouve dommage qu’il n’y ait pas de prise en charge du type stripping dans node_modules
    • C’était justement la moitié de la raison pour laquelle j’attendais cette fonctionnalité. Je voulais pouvoir écrire des bibliothèques en TypeScript, ne faire la vérification de types qu’en CI/CD, puis les importer directement dans Node.js
    • Je pense que c’est la bonne décision. TypeScript introduit des breaking changes assez souvent. Tant que ce n’est pas standardisé, l’approche actuelle me paraît préférable
  • Je n’utilise pas énormément JS/TS, mais je me demande s’il ne vaut pas simplement mieux utiliser Bun. Tous les projets ne démarrent pas de zéro bien sûr, mais j’ai eu l’impression que Bun est un meilleur runtime dans l’ensemble. Il exécute TS nativement, résout les dépendances bien plus vite et l’expérience d’utilisation est excellente. Personnellement, j’ai migré beaucoup d’anciens projets Node vers Bun, et depuis la sortie de Bun, je n’utilise presque plus Node. Si je me trompe sur certains points, je veux bien qu’on me corrige
    • Après presque 8 ans uniquement sur Node, je suis récemment passé à Deno. La transition n’a pas été simple, et ce n’était pas parce que ça ne fonctionnait pas, mais parce qu’il y avait toujours cette crainte de ne pas savoir quand ça allait casser. Node a clairement ses limites, mais ça reste malgré tout le standard de fait de l’industrie. L’écosystème JS est lui-même assez chaotique, et beaucoup de développeurs sont fatigués des nouveaux build tools, bundlers et runtimes. Je n’ai pas l’impression que Bun ait encore assez de stabilité ou de support pour devenir vraiment incontournable. J’ai déjà passé plusieurs jours à régler des problèmes causés par une simple mise à jour mineure de TS
    • Je n’aime pas trop courir après les dernières tendances. NodeJS est le runtime le mieux supporté de l’écosystème JS. Je pense qu’il vaut mieux suivre le choix par défaut. J’ai tendance à choisir des technologies dites « ennuyeuses »
    • J’ai essayé plusieurs fois de migrer complètement depuis la sortie de Bun, mais à chaque fois je me retrouve bloqué vers 90 % par un problème inévitable. Lors de ma dernière tentative, certaines bibliothèques ne fonctionnaient pas parce que des fonctions napi n’étaient pas implémentées, et je me souviens aussi d’un problème où recursive était ignoré dans les options de opendir. J’attends que Bun rattrape son retard, mais je n’ai pas encore l’impression qu’il soit prêt pour une adoption sérieuse sur de gros projets. Les fonctionnalités spécifiques à bun font bonne impression au départ, mais en pratique je les trouve encore insuffisantes. La documentation non plus n’atteint pas le niveau de qualité de celle de Node.js
    • Voici les problèmes de compatibilité que j’ai rencontrés en essayant de remplacer Node par Bun.
  • localAddress est ignoré dans les connexions TCP
  • Incompatibilité avec l’API des modules Node (exemple : le projet spamscanner ne fonctionne pas)
  • Problèmes de race autour de EventEmitter (partiellement résolus avec eventemitter2)
  • Le serveur de dev Svelte vites se bloquait parfois, au point qu’il fallait supprimer node_modules puis tout réinstaller
    • J’ai essayé les fonctionnalités TS et le runner de tests intégrés à Node lui-même, et ce n’est pas encore au niveau de Bun. Pour ce genre de besoins, j’utilise encore Bun pour l’instant. Dans l’écosystème Node, j’ai appris qu’il valait mieux combiner des outils spécialisés que tout miser sur un seul.

      • Bun.js : utilisé comme runtime Node, pour l’exécution TS et les tests. J’ai essayé plusieurs solutions comme TSX, TS-Node et Node lui-même

      • NPM : utilisé pour exécuter les scripts d’outillage

      • PNPM : utilisé pour installer les dépendances. (À mon avis, c’est le meilleur face à npm, yarn et bun)

      • Biome.js : pour le linting. Meilleur que tous les outils de linting que j’ai utilisés jusqu’ici

  • Ce qui est vraiment bien dans cette amélioration, c’est qu’elle repose uniquement sur le « type stripping », donc il n’y a pas besoin de source maps et en production c’est réellement à coût zéro. L’équipe Node a vraiment fait du bon travail
  • La fonction de suppression des types (import { stripTypeScriptTypes } from 'node:module') est aussi exposée. Pour développer une application web simple sans dépendances frontend, on peut tout écrire en typescript et servir aussi les scripts frontend en ne retirant que les types (projet d’exemple)
  • Grâce à ce changement, notre entreprise a enfin pu passer à Typescript. Nous avons migré plusieurs services vers TS d’un coup, et certains sont encore en cours. C’est une énorme avancée
  • On dirait que le fonctionnement consiste simplement à retirer les informations de type. Autrement dit, cela enlève une étape de transpilation, mais n’améliore pas la sûreté en soi
    • L’un des grands objectifs de conception de Typescript, c’est que si on enlève uniquement la syntaxe liée aux types, le résultat doit être un fichier JavaScript valide. Le compilateur TS ne génère pas de code (contrairement à PureScript, par exemple). On effectue les vérifications statiques avec un vérificateur de types comme tsc, puis les informations de type sont supprimées. Python aussi ignore les annotations de type à l’exécution, et Java supprime également certaines informations de type, notamment sur les génériques, dans le bytecode
    • Dire que « ça ne fait au mieux que supprimer une étape de transpilation sans améliorer la sûreté » est un peu trompeur. Le fait que Node puisse exécuter directement du TS n’améliore pas en soi la sûreté du typage, mais cette vérification peut déjà être faite séparément dans l’éditeur ou avec d’autres outils. En permettant l’exécution directe de TS, Node réduit fortement la barrière à l’entrée pour utiliser TS, et cela aide indirectement à la sûreté des types
    • Typescript n’a jamais promis d’améliorer à lui seul la sûreté. C’est un malentendu courant. TS n’a pas de mode ni d’informations de runtime, et sans lancer le vérificateur de types, on peut exécuter le code même avec de graves erreurs de type. Techniquement, Typescript est plus proche d’un linter
    • Je trouve extrêmement pratique de pouvoir exécuter directement des scripts sans build ni transpilation. Si j’ai besoin d’un contrôle de types, exécuter tsc me convient très bien
    • J’utilise déjà dans mes projets une configuration basée sur tsx qui permet exactement ça, c’est-à-dire exécuter sans build ni transpilation. En développement, c’est extrêmement utile. Grâce au --watch de tsx, je lance directement le serveur à partir du code source TS et il redémarre automatiquement au moindre changement. À l’avenir, on devrait pouvoir obtenir un environnement similaire avec nodemon et les fonctionnalités intégrées de Node. Pour faire aussi la vérification des types au runtime, il faudrait probablement un support au niveau de v8, ce qui reviendrait presque à une réécriture complète
  • En réalité, cela n’exécute pas tout Typescript, mais seulement un certain sous-ensemble. Le titre peut donc sembler exagéré. Ce genre de changement risque de pousser à utiliser TS seulement comme un linter, et des fonctionnalités TS puissantes qui ne peuvent pas être implémentées par simple type stripping pourraient tomber en désuétude
    • Je me demande quelles fonctionnalités de TS ne peuvent effectivement pas être gérées par stripping. En dehors de enum, quels cas d’usage réels existent ?