Entrevista con Mitchell Hashimoto: Ghostty, Zig y el mantenimiento de open source
(alexalejandre.com)- Mitchell Hashimoto, después de Vagrant, Terraform y Vault, ahora crea Ghostty y Vouch, y expone sus criterios sobre terminales, Zig, mantenimiento de open source y calidad de producto
- Ghostty comenzó como un proyecto personal para aprender programación con GPU, programación de sistemas de escritorio/de un solo nodo y Zig, y evolucionó con la meta de ser una terminal nativa, multiplataforma, rápida y rica en funciones
- En vez de intentar abarcarlo todo como un navegador, una terminal debería aprovechar la componibilidad de las apps basadas en texto, la automatización y un modelo de seguridad claro, aunque el flujo de bytes no estructurado del PTY sigue siendo una limitación
- Hashimoto cree que los mantenedores de open source no tienen obligaciones hacia los usuarios, pero que para hacer buen software hay que resolver varios problemas con una sola función coherente en lugar de aceptar cada solicitud tal cual
- Aunque los grandes cambios de Zig imponen una carga a quienes dependen de él, considera que están mejorando la calidad de la API y de las herramientas de compilación, y que la IA puede reducir el trabajo repetitivo de estos cambios a gran escala, disminuyendo la carga de compatibilidad hacia atrás
Por qué nació Ghostty
- Mitchell Hashimoto creó Vagrant, Packer, Consul, Terraform, Vault, Nomad y Waypoint, y ahora trabaja en Ghostty y Vouch
- Ghostty surgió de la inquietud de que, aunque llevaba unos 15 años creando aplicaciones CLI, nunca había entendido de verdad cómo funciona un emulador de terminal
- Después de dejar Hashicorp, había tres áreas a las que quería volver
- Programación con GPU en el contexto previo a la IA
- Programación de sistemas de escritorio/de un solo nodo, distinta a los sistemas distribuidos
- Uso de Zig
- El objetivo inicial era ejecutar vim y un compilador, hacer que Ghostty pudiera compilarse a sí mismo y luego desecharlo
- Al explorar más el ecosistema de terminales, concluyó que faltaba una herramienta rápida, rica en funciones, nativa y multiplataforma
- Después de compartirlo con amigos en Discord, empezaron a aparecer usuarios que lo usaban todos los días, y el Discord de Ghostty en realidad nació de convertir un chat grupal de amigos en un espacio dedicado
- Como consideraba que la visibilidad pública podía atraer una atención excesiva, lo mantuvo durante mucho tiempo en beta privada
Hasta dónde debería expandirse una terminal
- Hashimoto se opone a empujar la terminal sin más hacia una enorme plataforma de aplicaciones
- Una terminal podría incorporar acceso a video, micrófono e incluso layouts responsivos, como un navegador o el antiguo runtime de Java, pero él cree que el navegador, el escritorio y las apps de texto con grilla monoespaciada hacen bien cosas distintas
- Las aplicaciones basadas en texto se implementan rápido, son fáciles de operar y deben tener un modelo de seguridad claro
- La fortaleza de las apps de terminal está en su componibilidad
- Las TUI tienen esto en menor medida, pero la mayoría de las herramientas CLI tienen mecanismos que permiten usarlas más allá de stdin/stdout, casi como si fueran funciones
- La filosofía UNIX de “haz una sola cosa y hazla bien” es su forma más extrema
- Neovim y las herramientas de IA ofrecen cada vez más flags de línea de comandos
- Mejores aplicaciones de terminal llevan a mejor automatización y capacidad de scripting
- Las señales in-band del PTY, es decir, el flujo de bytes no estructurado que incluye secuencias de escape, sigue siendo un gran problema
- El ecosistema de Nushell intenta corregir esto en una capa separada, pero Hashimoto cree que hace falta una mejora más fundamental
- Aunque mucha gente no simpatiza con el ecosistema de Microsoft, valora que PowerShell hace muchas cosas bien en términos de datos estructurados
Una idea de API de terminal no heredada
- Al pensar en una nueva API de terminal, Hashimoto toma como referencia frameworks de grandes plataformas de aplicaciones como navegadores, Emacs, Apple, Microsoft, Android y consolas de videojuegos
- Cree que primero hay que estudiar precedentes ya acumulados, como el DOM y las API de JS de la web, AppKit, Cocoa y SwiftUI de Apple, Win32 y WinUI de Windows, o GTK y Qt en Linux
- Incluso para algo como el acceso al portapapeles, los protocolos históricos de terminal están centrados en texto, mientras que los escritorios han manejado imágenes y múltiples tipos MIME desde hace mucho tiempo, así que hay que revisar la documentación de portapapeles de cada plataforma
- Todavía no ha introducido protocolos personalizados en Ghostty
-
API de n-screen
- En las terminales actuales normalmente hay dos pantallas: main screen y alt screen
- La main screen se parece más al shell y al scrollback, y la alternate screen se parece más a Neovim y a la mayoría de las TUI
- Esta estructura consiste en activar o desactivar uno de esos dos modos, normalmente ocupando toda la pantalla y perdiendo el scrollback
- Hashimoto imagina una API de n-screen que permita crear y llenar en segundo plano una cantidad ilimitada de pantallas
- Cada pantalla podría tener un tamaño de grilla distinto y superponerse, mientras el emulador de terminal manejaría el ajuste de línea, la selección y el enrutamiento de eventos de mouse
- Si una pantalla específica se marca como ventana independiente, el emulador de terminal incluso podría renderizarla fuera de la grilla
- Como ejemplo, mencionó una forma de abrir pestañas de Neovim al mismo tiempo, como si fueran pestañas nativas de una ventana
-
Protocolo de botones
- Con el protocolo de mouse actual, un programa solo puede recibir eventos cuando el usuario hace clic en una celda de la grilla de la pantalla actual
- Los elementos del historial que ya entraron al scrollback no pueden recibir clics
- Hoy la terminal soporta el protocolo de hipervínculos OSC 8
- Hashimoto imagina un protocolo de botones similar a OSC 8, que al hacer clic envíe al programa un mensaje definido por este
- Por ejemplo, un botón con ID
open_profilepodría seguir registrado aunque el usuario haga scroll hacia el historial - Esta función afectaría a las aplicaciones de main screen con scrollback y se relaciona con el problema de que, en apps de main screen como Claude Code, abrir archivos o usar enlaces internos deja de funcionar cuando esos elementos pasan al historial
La falta de estándares y el mantenimiento de open source
- Hashimoto hizo un experimento para reemplazar todo el protocolo PTY con Wayland, pero lo descartó
- Considera que una terminal puede verse como un servidor de ventanas que administra ventanas y widgets, y que Wayland es un buen protocolo para resolver problemas de escritorio local y renderizado de ventanas
- Uno de los problemas de las terminales es que ya no existe un organismo de estandarización
- Las especificaciones antiguas siguen ahí, pero la estandarización de los últimos 20 años se ha guiado por lo que hace la terminal más popular del momento
- Como resultado, se mezclaron muchas funciones y, en su opinión, no hay ningún actor que impulse una visión con criterio propio
- No ha definido aún el camino a futuro, y cree que también sería posible crear un nuevo espacio para aplicaciones basadas en texto, distinto de la terminal, y poner encima una capa de traducción para apps heredadas
-
Equilibrio entre demandas de usuarios y una visión amplia
- Hashimoto ha dicho públicamente que los mantenedores de open source tienen cero obligaciones hacia los usuarios
- La primera línea de una licencia open source es “as is, no warranty”, y su postura es que el usuario recibe software gratis pero no adquiere derecho a exigir
- Al mismo tiempo, dice sentir responsabilidad por corregir problemas y mejorar el software porque quiere hacer buen software
- Algunos días revisa issues para arreglar problemas de otras personas, y otros días evita ver issues, discusiones y PR para concentrarse en lo que él quiere
- Cree que si todos los días solo atiendes issues de usuarios, el software se vuelve estable pero estancado; y si aceptas todos los PR, cambia, pero pierde visión
- Dice que la mayoría de las contribuciones apenas resuelven un problema individual muy específico, y que si se aceptan todas, el código se acumula como una montaña
- En cambio, si entiendes el problema a fondo, puedes resolver varias solicitudes de funciones a la vez con un sistema elegante
- En un video sobre diseño de funciones, mostró un caso donde cerró 3 o 4 solicitudes individuales y las resolvió al mismo tiempo con una sola función distinta
-
Diferenciar riqueza funcional de hinchazón
- La búsqueda, una de las funciones más pedidas en Ghostty, ya fue implementada y publicada
- Algunos usuarios criticaron que la búsqueda rompía el minimalismo de Ghostty y lo inflaba, pero Hashimoto respondió que Ghostty se promociona como una terminal rica en funciones
- Él distingue entre riqueza funcional e hinchazón
- La búsqueda ocupa espacio en disco y carga en RAM, pero fue diseñada para que, si no se usa, no ejecute ningún código
- Por eso considera que, para quien no la usa, es una función sin costo de ejecución
- Ghostty apunta a ser una terminal que puedas adaptar a tus necesidades, que funcione bien por defecto y que oculte funciones hasta que las necesites o las busques
- Ante la petición de mantener flags para eliminar funciones, opina que pedirle al mantenedor que administre esos flags es del mismo tipo que pedirle al usuario que mantenga un fork sin esa función
Derechos en open source, cambios en Zig y calidad de API
- Hashimoto cree que debería haber muchos más forks personales y forks mantenidos
- Considera que el open source financiado por venture capital creó una generación que espera proyectos muy pulidos, con sitio web, personal de soporte pagado y soporte por Slack o Discord
- Pero para él, el núcleo del open source no es la garantía del producto, sino la libertad y los derechos
- Usarlo como quieras
- Modificarlo
- Hacer fork
- La estabilidad o la obligación de mantenimiento no forman parte de esos derechos
- Dice que si entra un commit con una vulnerabilidad de seguridad, no se puede culpar solo al mantenedor; también hay responsabilidad del usuario por no revisar ese commit
- Si alguien quiere garantías más fuertes y el derecho de culpar a otra parte, entonces debe pagar por el software y establecer una relación proveedor-cliente
- En proyectos personales, puede incluso decidir no hacer merge de un PR que corrige un bug que él no sufre
- Porque hacer merge significa prometer que mantendrá ese código para siempre
-
Su postura sobre Zig
- Hashimoto sabía qué estaba aceptando al elegir Zig, y al trabajar en parches del compilador llegó a entender a la comunidad, su cultura y su filosofía
- Anticipa que los cambios de I/O, que aún no han comenzado, serán una de las tareas más difíciles en Zig
- Aunque la popularidad de Zig está subiendo, Andrew no retrocede en cambios que considera necesarios, y Hashimoto valora eso como usuario downstream
- Zig 0.15 cambió la interfaz de writer y afectó casi todo el código que produce salida, pero considera que la API en sí quedó mucho mejor
- Zig está muy enfocado en las herramientas de compilación e incluso ha eliminado funciones del lenguaje para acelerar la compilación
- Dice que hoy puede compilar instantáneamente toda la terminal de lib-ghostty, pero que Andrew considera que incluso ese tiempo en milisegundos sigue siendo demasiado lento
- Cree que Zig 1.0 llegará algún día, pero todavía faltan algunos años
- La IA puede reducir el dolor downstream causado por los cambios del lenguaje
- Cuenta que, después de mostrar en varios contextos cómo hacer una migración y dejar que la IA aplicara el resto, alrededor del 90% de un diff grande se resolvió automáticamente
- Si puedes explicar cómo pasar del estado A al estado B, eso sugiere un futuro en el que el significado de la compatibilidad hacia atrás se reduce
- Aunque es irónico dada la fuerte política anti-IA de Zig, cree que la IA amortigua el dolor que causan los cambios a los usuarios downstream
-
Bibliotecas y diseño de API
- El método más concreto para aprender buen diseño de bibliotecas es usar personalmente muchas bibliotecas de muchas comunidades
- Igual que aprenderías lenguajes de programación que no usarás en tu trabajo real, usar bibliotecas de distintos ecosistemas amplía la perspectiva
- En la universidad, creó productos de juguete con Prolog, Haskell, Clojure y Java, y así aprendió los sistemas de build, la usabilidad, las bibliotecas, los frameworks web, los servidores web y los servidores de aplicaciones de cada ecosistema
- Cree que la cultura de cada ecosistema se filtra en la separación de responsabilidades de bibliotecas y frameworks, y en la forma de sus API
- Mencionó como ejemplo de transferencia conceptual una ocasión en que probó en Ruby el patrón builder, muy usado desde hace tiempo en Java, y le pareció adecuado
- Dice que Docker mezcla en el flujo de desarrollo muchos elementos relacionados con despliegue y runtime, mientras que Vagrant usó de forma intencional sustantivos, CLI y configuración enfocados directamente en desarrollo
-
El dilema del creador de herramientas y el stack tecnológico
- Hashimoto dice que ha sido creador de herramientas toda su vida y que cree en el dilema del creador de herramientas
- Uno puede entender un problema con tanta profundidad que crea la herramienta ideal, pero si esa herramienta se vuelve popular, puede terminar siendo un creador de herramientas desconectado de los usuarios reales, y ese problema puede repetirse
- Aunque usa la terminal todos los días, no desarrolla suficientes TUI, y depende de mantenedores como rockorager, que mantiene varios clientes de email e IRC y también escribe especificaciones
- Sobre el stack tecnológico actual, su postura es básicamente que “está bien”
- Ve muchas cosas buenas en frontend, TypeScript y la comunidad de tipos de React, pero cree que hay demasiados cambios, mucha complejidad y capas de abstracción poco claras
- Dice que, como ocurrió al pasar de HTTP/1 a HTTP/2 y HTTP/3, en varias áreas la complejidad ha aumentado de forma no lineal
- Cree que la industria se mueve demasiado rápido y vuelve complejo lo que podría haber sido más simple, y que la IA y las herramientas relacionadas están acelerando eso
Principios, cultura, calidad y aprendizaje
- Dice que tanto el documento de principios de Hashicorp como la forma de desarrollar Ghostty eran reflejos personales suyos, por lo que le resultaba fácil practicarlos todos los días
- Cree que si estableces principios distintos a ti mismo, cuesta mucho llevarlos a la práctica real, como pasa con los propósitos de Año Nuevo
- Ghostty da importancia tanto a un núcleo multiplataforma como a una GUI nativa
- El núcleo es multiplataforma
- La GUI no insiste en ser multiplataforma y prefiere enfoques nativos de cada plataforma
- Cree que los proyectos open source y el internet deberían ser una colección de tribus distintas
- No le gusta que los lenguajes de programación se conviertan en un mínimo común denominador con todas las funciones que todos quieren, y dice que las restricciones crean creatividad y cultura
- Dijo que le gustan el lenguaje y la filosofía de Rust, pero no la cultura de Rust, y aclaró que eso no significa que la gente de su comunidad sea mala
- Zig tiene posturas claras y polarizantes en su tecnología, gestión comunitaria, financiamiento, PR, blog posts e incluso en la forma de hablar; Hashimoto dice que respeta esa rareza y por eso sigue usándolo y apoyándolo económicamente
- Para lanzar rápido sin perder calidad, hay que entender no solo el problema puntual de un cliente, sino también el contexto en el que el usuario llegó a ese problema y los problemas aguas arriba
- Dice que no sabe cómo resolver esto a escala empresarial, pero que él decide siendo un gran usuario de su propio software
- Cree que la IA puede usarse de forma tosca para demos o para confirmar una dirección, pero que el código que se va a publicar debe leerse, entenderse y entregarse con calidad
- En el aprendizaje de C, considera más importante entender cómo funciona la computadora que el lenguaje en sí
- Hay que entender el scheduling de CPU, la memoria, la jerarquía de caché, el sistema de archivos y cómo se accede al disco y a los archivos
- Si trabajas justo por encima de la capa de syscalls, como con C, Zig o Rust, es más fácil entender qué está pasando
- Las API para abrir archivos en Python, JavaScript o Ruby abstraen muchos detalles
- Aconseja no dar por sentadas ni siquiera las funciones de la biblioteca estándar: como son código que alguien escribió, conviene leerlas y profundizar en cómo funcionan
4 comentarios
Se publicaron casi al mismo tiempo, pero la vibra es tan distinta que resulta divertido jajajaja
Mis pensamientos sobre la reescritura de Bun en Rust
jaja...
jajajajajajajajajajajajajajajajajajajaja
Opiniones en Lobste.rs
Fue una entrevista excelente, y la frase que más me gustó fue: “No estoy de acuerdo con todo, pero de verdad respeto esa forma de ser orgullosamente rara”.
Ojalá hubiera más de esa actitud.
Si se va a hablar de precedentes y de la evolución de la terminal, creo que al menos habría que mencionar Arcan y cat9.
https://arcan-fe.com/2022/04/…
La parte de que “PowerShell maneja bien los datos estructurados” me recordó esta respuesta de Jörg W Mittag.
Si usas argumentos tipados, PowerShell se encarga de todo el parsing.
También es genial imaginar pestañas de Neovim abriéndose simultáneamente como pestañas nativas de ventana.
Trabajar justo encima de la capa de llamadas al sistema, como en C, Zig o Rust, ayuda muchísimo a entender qué está pasando.
El proceso de quitar abstracciones entre la máquina y el programador para llegar a la capa base es divertido y te acerca más a la esencia del problema.
Como las bibliotecas estándar suelen apuntar a la portabilidad, terminan conteniendo el mínimo común denominador de las funciones del sistema operativo; programar se vuelve mucho más disfrutable cuando puedes aprovechar al máximo la plataforma.
Siento mucho respeto por la actitud de no dar por sentadas las funciones de la biblioteca estándar y leerlas, porque también son código escrito por alguien.
También quisiera saber más sobre el programa de patrocinio de Ghostty. Parece haberse constituido como una entidad sin fines de lucro, y me da curiosidad qué tan exitoso y autosustentable es.
PowerShell en Windows tiene la ventaja de ser completamente interno según esta definición, pero como está construido sobre el framework .NET, puede acceder e interoperar con casi todas las API de Windows, así que en la práctica no está muy limitado.
UNIX es externo por diseño, y la respuesta estructurada de Nushell, según entiendo, es estrictamente interna, por lo que escala peor.
Oils apuesta por json o su propia extensión json8 para la interoperabilidad estructurada externa, pero ambos se sienten bastante limitados en comparación con PowerShell.
Me pregunto qué pasaría si todos acordáramos enviar por stdout solo algo como msgpack y convirtiéramos todas las terminales en visores de msgpack. Quizá habría que hacer una petición para meter serialización/deserialización de pipes en libc.
No solo desapareció el organismo de estandarización de terminales; en el mundo de los shells también casi no ha habido innovación a nivel de producción.
Bash todavía sigue agregando funciones que ya existían en Kornshell, los shells de Unix tienen demasiadas trampas que nadie sabe cómo eliminar, y POSIX casi no se mueve.
Todavía mantengo el sueño de que Oils o Nushell sean adoptados por distribuciones importantes y la gente se dé cuenta de que innovar en esta área es algo bueno.
Aun así, kitty claramente abrió camino en el espacio de las terminales y, aunque falta coordinación, parece que ya llegamos a una etapa donde sí está ocurriendo innovación.
Llegué a respetar mucho los juicios serenos, tanto positivos como negativos, de Mitchell.
Construye una terminal excelente y le gustan las interfaces de terminal, pero no está de acuerdo con que la terminal lo haga todo ni con llevarla al extremo.
Se preocupa profundamente por los lenguajes de programación y sus comunidades, y quiere que cada lenguaje tenga una identidad propia, pero también sabe que al final los lenguajes son medios para un fin y que la comprensión de lo subyacente es más importante.
Reconoce que personalmente le desagrada la comunidad de Rust, pero no menosprecia a quienes sienten lo contrario.
Me impresiona esa actitud bastante zen: ve internet como un conjunto de muchas tribus, pero no cae en el tribalismo ni en la búsqueda de la “única tribu verdadera”.
Estoy de acuerdo con la idea de que debería haber más forks personales/de mantenimiento, pero no tengo claro cómo fomentarlo.
En el extremo bajo del espectro de sensación de derecho, quizá a la gente no le interesen elementos empresariales como contratos de soporte pagados, y solo quiera la comodidad de poder instalarlo tal cual desde su gestor de paquetes favorito.
De alguna forma hay que reducir la fricción inicial de pasar de
brew installoapt installa lidiar con repositorios clonados y herramientas de build.Compiladores más rápidos podrían ayudar.
Dicho eso, en software sensible a la seguridad puede convenir que los usuarios no hagan demasiados cambios, así que a veces esa fricción en sí misma es una función.
Estoy muy de acuerdo en que las UI modernas necesitan algo a medio camino entre n-screen y una especificación de botones.
Quizá bastaría con llamarlo capa semántica.
Con esa capa se vuelven posibles herramientas de tipo agente o de pantalla principal, accesibilidad, widgets y controles componibles, y cosas por el estilo.
n-screen y los botones parecen ser, al final, los límites izquierdo y derecho de cuánta información se expresa.
Idealmente, esa capa semántica también debería traer cosas como cursores múltiples, saltos de línea por palabra en vez de por carácter, y overlays (z-index, mezcla de celdas, etc.).