Saltar al contenido

Cómo crear una CLI que otros quieran usar

4 min de lectura Software
  • cli
  • ux
  • node.js
  • software
  • desarrollo

Una herramienta de línea de comandos, o CLI, no es solo una forma de ejecutar código; es una interfaz de usuario. Puedes tener la funcionalidad más potente del mundo, pero si tu herramienta es confusa, nadie la usará. El problema no es que el código funcione, sino que la gente lo entienda sin leer la documentación completa.

Mi regla es simple: una herramienta de línea de comandos debe ser intuitiva incluso para quien la usa por primera vez. Esto significa pensar en la experiencia del usuario (UX) desde el primer comando.

Diferencia entre una CLI funcional y una usable

La diferencia entre una CLI funcional y una usable no reside en su potencia, sino en su claridad. Una CLI funcional ejecuta tareas, pero una usable guía al usuario, proporciona feedback y previene errores.

Un comando usable tiene una estructura predecible, sus argumentos tienen sentido y sus mensajes de error son específicos. No hay que adivinar qué hace cada opción o por qué algo falló.

Argumentos claros y bien definidos

La forma en que manejas los argumentos en tu CLI es clave para su usabilidad. Un argumento ambiguo o inconsistente genera frustración. Utiliza nombres completos para las opciones (--verbose) y abreviaturas coherentes (-v). Asegúrate de que los argumentos requeridos sean explícitos y los opcionales tengan valores por defecto sensatos.

En Node.js, herramientas como commander o yargs simplifican esta tarea. Permiten definir comandos, opciones y validaciones con poco código, generando automáticamente la ayuda. Esto es lo que hago para construir herramientas robustas.

// Ejemplo con Commander.js
const { program } = require('commander');

program
  .name('mi-cli')
  .description('Una CLI para gestionar proyectos')
  .version('1.0.0');

program.command('crear <nombre>')
  .description('Crea un nuevo proyecto con el nombre especificado')
  .option('-p, --path <ruta>', 'Ruta donde crear el proyecto', process.cwd())
  .action((nombre, options) => {
    console.log(`Creando proyecto "${nombre}" en ${options.path}...`);
    // Lógica para crear el proyecto
  });

program.parse(process.argv);

Este tipo de herramientas no solo parsean argumentos, sino que también generan una sección de ayuda útil. Si quieres que otros entiendan tu código, más allá de la CLI, te recomiendo leer sobre la documentación de código en proyectos solitarios.

Feedback inmediato y errores útiles

Cuando tu herramienta está haciendo algo que lleva tiempo, el usuario necesita saber que no se ha colgado. Barras de progreso, spinners o mensajes de estado intermedios son necesarios. Si la herramienta falla, el mensaje de error debe ser lo suficientemente específico como para que el usuario sepa cómo solucionarlo, no un simple “Error inesperado”.

Un buen mensaje de error señala el argumento incorrecto, el archivo que falta o la red que no responde. Esto reduce el tiempo que el usuario dedica a depurar y aumenta la confianza en tu herramienta. La validación temprana de argumentos también previene errores lógicos más complejos.

Equilibrio entre flexibilidad y simplicidad

Diseñar una herramienta usable implica encontrar un equilibrio entre ofrecer suficientes opciones para ser flexible y no abrumar al usuario con demasiadas. Añadir cada posible argumento puede hacer la herramienta potente, pero también compleja de aprender. Es una navaja suiza que pocos saben manejar.

Lo que ganas:

  • Una herramienta que resuelve un espectro amplio de problemas, adaptable a diferentes escenarios sin modificar el código.
  • Control granular sobre cada aspecto de la ejecución, ideal para usuarios avanzados o scripts automáticos.
  • Menos necesidad de construir múltiples herramientas para variaciones de una misma tarea.

Lo que complicas:

  • Mayor curva de aprendizaje para usuarios nuevos, que pueden sentirse abrumados por la cantidad de opciones.
  • Más trabajo de documentación y ejemplos para cubrir todos los casos de uso.
  • Riesgo de que la herramienta se perciba como “demasiado compleja” y se use menos.

Mi enfoque es empezar simple y añadir complejidad solo cuando un caso de uso real lo justifica.

Estructura interna y mantenimiento de la CLI

Una CLI bien diseñada externamente requiere una buena estructura interna. Separa la lógica de parsing de argumentos de la lógica de negocio. Utiliza módulos y funciones claras para cada comando y sus subcomandos. Esto facilita el mantenimiento, la adición de nuevas funcionalidades y, sobre todo, la realización de testing automatizado que ahorra dinero.

Una herramienta que no se puede mantener o testear es un pasivo, no un activo. La misma disciplina que aplicas al desarrollo de un backend se aplica aquí.

Si quieres profundizar en cómo escribir código que se entienda sin esfuerzo, te recomiendo este artículo sobre funciones legibles sin comentarios. También es útil revisar los principios para nombrar cosas en el código con buenas prácticas para que tus comandos y argumentos sean intuitivos. Si buscas integrar tu CLI con otros sistemas, entender el diseño correcto de una API REST es clave. Para proyectos más grandes donde la CLI es parte de un sistema complejo, considera cuándo usar arquitectura hexagonal para mantenerla mantenible.

Lucas Juárez
Lucas Juárez

Técnico freelance especializado en desarrollo a medida, automatizaciones con IA y gestión técnica para negocios en España. Más sobre mí →

Compartir:

¿Necesitas desarrollo a medida?

Desarrollo funcionalidades específicas, integraciones entre sistemas y herramientas internas. Si se puede programar, probablemente puedo hacerlo.

Chat