Back

Créer des interfaces terminal avec Node.js

Créer des interfaces terminal avec Node.js

Votre outil CLI fonctionne, mais il ressemble à quelque chose de 1985. Les utilisateurs attendent plus que de simples invites textuelles—ils veulent des tableaux de bord interactifs, des mises à jour en temps réel et une navigation au clavier. C’est là qu’interviennent les interfaces utilisateur terminal (TUI), et Node.js 22 LTS fournit tout ce dont vous avez besoin pour les créer.

Ce guide couvre les primitives essentielles pour le développement d’interfaces utilisateur terminal avec Node.js, examine l’écosystème TUI moderne et montre comment des frameworks comme Ink et neo-blessed s’intègrent dans les outils CLI de production.

Points clés à retenir

  • Les TUI maintiennent des affichages persistants et interactifs, contrairement aux CLI simples qui acceptent des arguments, s’exécutent et se ferment
  • Node.js 22 fournit des primitives essentielles comme le mode raw, les événements de redimensionnement et la gestion des flux pour créer des interfaces terminal
  • Ink apporte le modèle de composants de React aux terminaux, ce qui le rend idéal pour les développeurs familiers avec JSX
  • neo-blessed perpétue l’héritage de blessed pour les dispositions traditionnelles basées sur des widgets avec support de la souris
  • Combinez des frameworks CLI comme oclif avec des bibliothèques TUI pour créer des outils en ligne de commande organisés et riches en fonctionnalités

Ce qui distingue les TUI des CLI simples

Un CLI accepte des arguments, s’exécute et se ferme. Un TUI maintient un affichage persistant et interactif. Pensez à htop versus ls.

Les TUI ont du sens lorsque vous avez besoin de :

  • Visualisation de données en temps réel (tableaux de bord de surveillance, suivi de progression)
  • Navigation complexe (dispositions multi-panneaux, listes déroulantes)
  • État persistant pendant l’interaction utilisateur
  • Retour d’information riche au-delà d’une sortie texte séquentielle

Pour le développement TUI avec Node.js 22, comprendre les primitives sous-jacentes vous aide à choisir le bon niveau d’abstraction.

Primitives terminal essentielles dans Node.js 22

stdin, stdout et mode Raw

Node.js expose process.stdin et process.stdout en tant que flux. Pour les TUI, vous activerez généralement le mode raw sur stdin :

import * as readline from  'node:readline'

process.stdin.setRawMode(true)
readline.emitKeypressEvents(process.stdin)

Le mode raw envoie chaque frappe de touche immédiatement plutôt que d’attendre Entrée. Cela permet la gestion des entrées clavier en temps réel—essentielle pour toute interface interactive.

Séquences d’échappement ANSI

Les terminaux interprètent des séquences de caractères spéciales pour le style et le contrôle du curseur. Déplacer le curseur, effacer des lignes et appliquer des couleurs utilisent tous des codes ANSI. Les bibliothèques abstraient cela, mais savoir qu’ils existent aide au débogage.

Événements de redimensionnement

Les terminaux se redimensionnent. Votre TUI doit réagir :

process.stdout.on('resize', () => {
  const { columns, rows } = process.stdout
  // Redessinez votre interface
})

Support Unicode et couleur

Les terminaux modernes gèrent bien l’Unicode, mais les sessions SSH et les émulateurs plus anciens varient. Vérifiez process.stdout.isTTY avant de supposer le support des couleurs, et envisagez des solutions de repli pour les environnements où TERM indique des capacités limitées.

L’écosystème TUI moderne

Ink : React pour les terminaux

Ink domine aujourd’hui le développement d’interfaces terminal. Il apporte le modèle de composants de React au terminal—vous écrivez du JSX, et Ink gère le rendu.

import React from 'react'
import { render, Text, Box } from 'ink'

const App = () => (
  <Box flexDirection="column">
    <Text color="green">Statut : En cours d'exécution</Text>
  </Box>
)

render(<App />)

L’outillage environnant renforce la position d’Ink :

  • @inkjs/ui fournit des composants prêts à l’emploi (spinners, entrées de sélection, barres de progression)
  • create-ink-app échafaude de nouveaux projets
  • Pastel offre une couche de framework pour les applications Ink plus volumineuses

Si vous êtes à l’aise avec React, Ink vous semblera immédiatement familier.

La famille Blessed : tableaux de bord neo-blessed

La bibliothèque originale blessed a été pionnière dans les interfaces utilisateur terminal riches pour Node.js avec des widgets, des dispositions et un support de la souris. Elle n’est aujourd’hui pratiquement plus maintenue.

neo-blessed et reblessed poursuivent le développement. Ces forks reçoivent des mises à jour occasionnelles et corrigent les problèmes de compatibilité avec les versions modernes de Node.

Avec les tableaux de bord neo-blessed, vous obtenez :

  • Dispositions en boîtes, listes, tableaux et formulaires
  • Support de la souris
  • Défilement et gestion du focus
  • Widgets blessed-contrib (graphiques, jauges, cartes)

Choisissez les bibliothèques de la famille blessed lorsque vous avez besoin de dispositions traditionnelles basées sur des widgets plutôt que du modèle déclaratif de React.

Associer les couches TUI avec des frameworks CLI

Construire un CLI Node.js avec oclif vous donne l’analyse d’arguments, l’organisation des commandes et une architecture de plugins. Mais oclif gère la couche CLI—il ne rend pas les interfaces.

Le modèle : utilisez oclif pour la structure des commandes, puis rendez les composants TUI dans des commandes spécifiques :

import { Command } from '@oclif/core'
import { render } from 'ink'
import Dashboard from './components/Dashboard.js'

export default class Monitor extends Command {
  async run() {
    render(<Dashboard />)
  }
}

Cette séparation maintient votre outil multi-commandes organisé tout en permettant des interfaces riches là où c’est nécessaire.

Choisir votre approche

BesoinSolution
Familiarité avec React, réutilisation de composantsInk
Widgets traditionnels, dispositions complexesneo-blessed
Structure CLI multi-commandesoclif + couche TUI
Invites simples uniquementInquirer ou readline brut

Conclusion

Commencez par les primitives—comprenez le mode raw et la gestion du redimensionnement. Ensuite, choisissez l’abstraction qui correspond à votre modèle mental : Ink pour les développeurs React, neo-blessed pour une approche basée sur les widgets.

Le terminal n’est pas une limitation. Avec les API modernes de Node.js 22 et ces frameworks, vous pouvez créer des interfaces qui rivalisent avec les outils graphiques tout en conservant l’efficacité de la ligne de commande.

FAQ

Oui, Ink a un support complet de TypeScript. La bibliothèque est livrée avec des définitions de types, et create-ink-app peut échafauder des projets TypeScript directement. La plupart des packages de l'écosystème Ink comme @inkjs/ui incluent également des types TypeScript prêts à l'emploi.

Écoutez les signaux SIGINT et SIGTERM sur l'objet process. Dans Ink, appelez la fonction unmount retournée par render() avant de quitter. Pour neo-blessed, appelez screen.destroy(). Restaurez toujours l'état du terminal en désactivant le mode raw et en effaçant le tampon d'écran alternatif.

Généralement oui, mais avec des réserves. Les sessions SSH peuvent avoir un support limité des couleurs ou des dimensions de terminal différentes. Vérifiez toujours process.stdout.isTTY et la variable d'environnement TERM. Testez avec des clients SSH courants et envisagez de fournir un mode de repli simplifié pour les environnements contraints.

Bien que techniquement possible, ce n'est pas recommandé. Les deux bibliothèques gèrent l'état du terminal différemment et peuvent entrer en conflit lors du rendu. Choisissez une approche par commande ou interface. Si vous avez besoin de fonctionnalités des deux, envisagez d'utiliser oclif pour séparer les commandes qui utilisent différentes bibliothèques TUI.

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay