Todos los posts
SwiftSwiftUImacOSOpen SourceSide ProjectAI Workflows

Harto de visores de Markdown inflados o de pago, hice el mío: nativo, 9 MB, gratis y open source, con IA, en una tarde

Los visores de Markdown que encontraba para Mac eran inflados, de pago o por suscripción, y mediocres. Construí MdViewer: un visor nativo de solo lectura para macOS, de 9,1 MB, gratis y open source. Lo hice en una tarde, en pareja con Claude Code.

24 de septiembre de 20265 min de lectura

Leo Markdown todo el día. READMEs, specs, notas, documentación de proyectos. Y cada vez que quería simplemente abrir un .md en el Mac y leerlo bien renderizado, acababa en el mismo sitio: apps infladas, con paywall o suscripción para algo tan trivial como mostrar un archivo de texto con formato, y encima mediocres. En mi opinión, una porquería.

No pedía un editor. No pedía sincronización en la nube ni una IA que me resuma el README. Pedía un visor. Que abra rápido, que se vea bien y que no me cobre todos los meses.

Así que me hice el mío: MdViewer. Nativo, 9,1 MB instalado, gratis y open source. Y lo construí en una tarde, en pareja con IA.

MdViewer mostrando un documento con el outline en la barra lateral y diagramas Mermaid renderizados
Outline con scroll-spy a la izquierda, diagramas Mermaid a la derecha

Qué hace

Es un visor de Markdown de solo lectura para macOS 15 o superior, universal (Apple silicon e Intel). Lo que trae:

MdViewer renderizando fórmulas matemáticas con KaTeX
KaTeX, sin conexión y sin nada que instalar aparte

Cómo lo construí con IA

Todo salió en una sola tarde, trabajando con Claude Code. Pero no fue "escribí un prompt y salió una app". El flujo fue bastante más ordenado que eso.

Primero, la IA investigó opciones y me propuso un plan en cuatro fases:

  1. MVP: abrir un archivo y renderizarlo bien.
  2. Comodidad de lectura: outline, recarga en vivo y búsqueda.
  3. Contenido rico: PDF, matemáticas, diagramas y temas.
  4. Integración con macOS: Quick Look y release.

Yo tomaba las decisiones; la IA implementaba cada fase. Por ejemplo, para el renderizado me planteó tres enfoques distintos, con sus pros y contras, y elegí yo. Ese reparto funciona: la IA es muy buena explorando el espacio de soluciones, pero la dirección del producto tiene que tener dueño.

Lo que más me sorprendió fue la verificación. Al cerrar cada fase, la IA compilaba, corría los tests y sacaba capturas de pantalla de la app en ejecución para comprobar que lo que decía que funcionaba, funcionaba de verdad. Hasta el icono de la app lo generó programáticamente, con un script de CoreGraphics.

Dónde tuve que meterme yo: algunas interacciones de la interfaz había que probarlas a mano, porque no todo se valida con una captura. Y hay cosas que no dependen del código: la app no está notarizada, porque eso requiere una cuenta de Apple Developer de pago.

Mi conclusión es la misma de siempre: la IA acelera muchísimo, pero decidir qué construir y responder por el resultado sigue siendo trabajo mío.


La parte técnica, corta

La decisión que más me importaba: WebKit solo renderiza el documento. WKWebView pinta el contenido del Markdown, y todo lo demás (ventanas, barra lateral, menús, temas) es SwiftUI nativo. Así la app se siente de Mac, y no una web metida en una ventana.

Y un gotcha que conviene conocer si alguna vez hacés una extensión de Quick Look: dentro de su sandbox, WKWebView renderiza en blanco si la extensión no tiene el entitlement com.apple.security.network.client. Aunque todo el contenido sea local, WebKit lo necesita igual. Sin él, la vista previa sale vacía.


Cómo instalarlo

No está en la Mac App Store: se distribuye por GitHub Releases.

  1. Descargá el .zip de la release v0.1.0.
  2. Mové MdViewer.app a /Applications.
  3. Como no está notarizada, quitale la cuarentena desde la terminal:
xattr -dr com.apple.quarantine /Applications/MdViewer.app

Y listo. Abrí cualquier .md o apretá Espacio sobre uno en el Finder.


Links

Si también estás harto de pagar por leer un README, probalo. Y si encontrás un bug o te falta algo, los issues están abiertos.