design

Markdown a HTML: Qué convertidor para qué trabajo (y el cheatsheet)

El mismo archivo Markdown produce HTML diferente según la herramienta. Qué convertidor para cada trabajo — navegador, pandoc, Python, JS, VS Code — más el cheatsheet.

Published 2026-09-03 · 8 min read

Affiliate disclosure

Some links below are affiliate links. I may earn a commission from qualifying purchases at no extra cost to you. Recommendations come from published specifications and independent reviews, not hands-on testing.

Conversión de Markdown a HTML en la pantalla del portátil de un desarrollador — ilustración hero original
AI illustration

Pega un archivo Markdown en dos convertidores diferentes y puedes obtener dos documentos distintos. No diferente formato, sino diferente estructura. Una tabla que se convierte en una verdadera <table> en una herramienta sale como un párrafo lleno de caracteres de tubería en otra, y ninguna herramienta está rota.

Esa es la parte que la mayoría de guías de "markdown a html converter" se saltan, y es la parte que decide qué herramienta deberías realmente usar.

TL;DR — Para un pegado único, usa un convertidor de navegador como nuestra herramienta Markdown a HTML. Para trabajos por lotes y pipelines de docs, usa pandoc. Para convertir dentro de tu propia app, usa markdown-it (JavaScript) o el paquete markdown (Python). Si el Markdown vino de un usuario, sanitiza el HTML después con DOMPurify sin importar qué convertidor lo produjo.

¿Por qué el mismo Markdown produce HTML diferente?

No hay un único Markdown. El lanzamiento original de 2004 por John Gruber y Aaron Swartz fue un script Perl y una descripción en prosa, no una especificación, e implementaciones se desviaron durante una década.

CommonMark existe para terminar esa desviación. Es una especificación precisa, actualmente versión 0.31.2 y lanzada en enero de 2024, iniciada en 2014 por John MacFarlane con ingenieros de GitHub, Reddit, Stack Overflow y Discourse. GitHub Flavored Markdown es un superconjunto estricto de CommonMark que añade tablas, tachado, listas de tareas y autoenlaces.

La brecha entre esos dos es donde viven la mayoría de las sorpresas. Toma esta entrada:

| Fruit | Qty |
|---|---|
| Apple | 3 |
| Pear  | 5 |

Convertido con pandoc -f commonmark -t html, las tuberías son texto literal:

<p>| Fruit | Qty | |---|---| | Apple | 3 | | Pear | 5 |</p>

Convertido con pandoc -f gfm -t html, obtienes la tabla que esperabas:

<table><thead><tr><th>Fruit</th><th>Qty</th></tr></thead>
<tbody><tr><td>Apple</td><td>3</td></tr><tr><td>Pear</td><td>5</td></tr></tbody></table>

Mismo archivo, mismo programa, un flag de diferencia. La misma división se reproduce en una base de código no relacionada: new MarkdownIt('commonmark') renderiza ~~strike~~ como texto literal, mientras que new MarkdownIt() renderiza <s>strike</s>. Así que esto no es una particularidad de pandoc. Es el límite CommonMark/GFM mismo.

Consecuencia práctica: cuando la salida se ve mal, la primera pregunta no es "¿está rota esta herramienta?" sino "¿qué sabor está analizando esta herramienta?".

¿Cómo puedes saber qué sabor usa un convertidor?

La mayoría de convertidores en línea nunca estados qué parser está detrás, así que pruébalo en lugar de confiar en él. Pega esta sonda de cuatro líneas en cualquier herramienta y lee la salida:

| a | b |
|---|---|
| 1 | 2 |

~~strike~~ and a task: - [x] done

Si la tabla se renderiza como una tabla y strike sale tachado, estás en un parser capaz de GFM. Si alguno viene como puntuación literal, la herramienta está ejecutándose más cerca de CommonMark simple, y cualquier documento que conviertas con ella perderá silenciosamente esos constructos. Silenciosamente es la palabra operativa: nada produce error, la salida solo pierde silenciosamente estructura.

Hay una tercera familia que vale la pena conocer, porque explica salida que no coincide con ninguno de los dos resultados. PHP Markdown Extra, mantenida por Michel Fortin desde 2003, añade notas al pie, listas de definiciones, abreviaciones e IDs de atributo como {#id}. Está detrás de gran parte del ecosistema PHP y CMSs antiguos, así que un archivo que se renderiza de una manera en una herramienta de la era WordPress y de otra manera en GitHub generalmente está cruzando ese límite en lugar de golpear un bug.

¿Qué convertidor deberías usar para qué trabajo?

MétodoCosto de configuraciónMejor paraMal ajustado para
Herramienta de navegadorCeroPegado único, sin instalación, funciona en móvilAutomatización; texto confidencial que no has verificado
CLI pandocMedio (~279MB)Conversión por lotes, pipelines de docs, muchos formatos de salidaUn único pegado rápido; incrustar en una solicitud web
Python (markdown)Bajo (pip)Backends Django/Flask, generadores de sitios estáticosRenderizado del lado del cliente
JS (markdown-it, marked)Bajo (npm)Aplicaciones web, vista previa en vivo, backends NodeScripts únicos internos
Extensión VS CodeBajo, una vezDesarrolladores ya escribiendo docs en el editorUsuarios no técnicos, automatización

¿Cuándo es pandoc la herramienta correcta?

Pandoc es la herramienta correcta una vez que estés convirtiendo más que un puñado de archivos, o convirtiendo a varios formatos desde una fuente. La versión 3.11 es actual.

brew install pandoc                       # macOS
winget install --exact --id JohnMacFarlane.Pandoc   # Windows

En Debian y Ubuntu, apt install pandoc funciona pero se envía muy atrás. Ubuntu 26.04 lleva 3.7.0.2 y algunas ramas de Debian son más antiguas. Si necesitas comportamiento actual, toma el .deb de la página de lanzamientos en su lugar.

pandoc input.md -o output.html      # HTML fragment
pandoc -s input.md -o output.html   # standalone document with <html> and <head>

El flag -f es el selector de sabor que la sección anterior es realmente acerca de: -f commonmark, -f gfm, -f markdown_strict, o el dialecto extendido propio de pandoc por defecto.

Una advertencia que vale la pena conocer antes de que hagas diff de la salida contra otra herramienta: pandoc no emite un simple <pre><code> para bloques de código vallado. Los envuelve en <div class="sourceCode"> con spans de resaltado de sintaxis. Esa es una elección deliberada, no un bug, pero significa que el HTML de pandoc no es byte-comparable con las librerías de abajo.

Salta pandoc si estás convirtiendo un párrafo pegado único. Una instalación de 279MB para convertir un changelog una vez es el intercambio equivocado, y pandoc es un binario nativo — realizar shell a él dentro de una ruta de solicitud web para procesar entrada de usuario es un olor operacional y de seguridad.

¿Cómo conviertes Markdown dentro de tu propia app?

Python. El paquete markdown es la respuesta común. El lanzamiento actual es 3.10.3, pero nota que requiere Python 3.10 o más nuevo — en Python 3.9, pip install Markdown silenciosamente resuelve a 3.9 en lugar de fallar.

import markdown
html = markdown.markdown(text)                                        # bare
html = markdown.markdown(text, extensions=['tables', 'fenced_code'])  # tables + code blocks

Esa segunda línea importa más de lo que parece. Sin fenced_code, un bloque de triple-backtick no se convierte en <pre><code> para nada — se colapsa en una única ejecución inline <code> dentro de un párrafo. Si alguna vez te preguntaste por qué tus muestras de código salieron destrozadas, usualmente es por qué. markdown-it-py (4.2.0) es la alternativa cuando quieres cumplimiento estricto de CommonMark o una arquitectura de plugin.

JavaScript. Dos librerías dominan, y la diferencia entre ellas es una postura de seguridad, no una lista de características.

npm install markdown-it   # or: npm install marked
import MarkdownIt from 'markdown-it';
const html = new MarkdownIt().render('# markdown-it rulezz!');

marked (18.0.11) es rápido y permisivo: HTML crudo pasa intacto por defecto. markdown-it (15.0.1) es conforme a CommonMark y escapa HTML crudo por defecto, y html: false es el literal por defecto en su fuente de preset propio. Para una aplicación web que renderiza Markdown que no escribiste, ese es el defecto que quieres.

¿Es seguro convertir Markdown que no escribiste?

Markdown permite HTML inline por diseño, así que un convertidor no es un sanitizador y principalmente no reclama serlo. Dale a ambas librerías la cadena Hello <script>alert(1)</script> con opciones por defecto y no están de acuerdo: marked emite la etiqueta de script intacta, markdown-it la escapa a texto inofensivo.

marked solía enviar opciones sanitize y sanitizer. Ambas fueron deprecadas en v0.7.0 y removidas en v8.0.0; la documentación de la librería ahora apunta a DOMPurify (3.4.14) en su lugar:

import DOMPurify from 'dompurify';
const clean = DOMPurify.sanitize(marked.parse(input));

Tres cosas siguen. Sanitiza siempre que el Markdown sea enviado por usuario — comentarios, wikis, rastreadores de problemas, cualquier cosa que no hayas escrito. Hazlo sin importar la librería, porque el defecto seguro de markdown-it está a un html: true de distancia de ser inseguro y el paquete markdown de Python tampoco sanitiza. Y nota que DOMPurify es basado en DOM: en el navegador funciona nativamente, pero del lado del servidor en Node necesita jsdom.

Si solo necesitas mostrar Markdown como texto visible en lugar de renderizarlo, escapar los corchetes angulares con un codificador de entidad HTML se salta la pregunta completamente.

Cheatsheet de Markdown a HTML

MarkdownHTMLEspecificación
# H1###### H6<h1><h6>CommonMark
**bold**<strong>CommonMark
*italic*<em>CommonMark
`code`<code>CommonMark
[text](url)<a href="url">CommonMark
![alt](url)<img src="url" alt="alt">CommonMark
- item<ul><li>CommonMark
1. item<ol><li>CommonMark
> quote<blockquote><p>CommonMark
fenced block<pre><code class="language-…">CommonMark
---<hr>CommonMark
~~text~~<del> (MDN)GFM only
| a | b |<table><thead>…<tbody>GFM only
- [x] done<li><input type="checkbox" checked disabled>GFM only

Las tres filas GFM-only son los que se rompen cuando mueves un archivo de GitHub a un parser más estricto.

¿Cómo exportas a HTML desde VS Code o un navegador?

La vista previa incorporada de VS Code (Cmd+Shift+V, o Ctrl+Shift+V) renderiza Markdown pero no lo exporta. La documentación no describe ningún comando incorporado de guardar-como-HTML. Añade Markdown All in One (yzhang.markdown-all-in-one) y su comando "Print current document to HTML", o Markdown PDF (yzane.markdown-pdf), que exporta HTML también a pesar del nombre.

Los convertidores de navegador son la ruta más rápida para un pegado único y el único que funciona en un móvil. El intercambio es que la mayoría no divulgan qué parser usan, así que no puedes asumir un sabor, y deberías saber si el texto deja tu dispositivo. Eso es comprobable en alrededor de diez segundos: abre devtools, mira la pestaña Network, ejecuta la conversión, y busca un POST saliente llevando tu texto. Una herramienta genuinamente del lado del cliente no hace ninguna solicitud para nada. Haz ese verificar antes de pegar cualquier cosa propietaria.

Veredicto

Elige por trabajo, no por popularidad. Un pegado único quiere un convertidor de navegador; un pipeline de docs quiere pandoc; una aplicación que renderiza Markdown quiere markdown-it más DOMPurify. La única regla que abarca todos es que Markdown es una familia de dialectos en lugar de un formato, así que nombra tu sabor antes de depurar tu salida — y si también trabajas en formatos de configuración, la misma lección se aplica a elegir entre JSON, YAML y TOML y a saber cuándo una herramienta de navegador le gana a un CLI.

Lo que no deberías hacer es escribir el convertidor tú mismo. Asteriscos desequilibrados, literales escapados, énfasis dentro de texto de enlace y espacios de código con backtick doble todos se analizan correctamente bajo una librería real y todos se rompen una cadena de reemplazos regex. La gramática de Markdown es sensible al contexto; un npm install te compra una década de casos extremos ya manejados.

Sigue leyendo

Software de edición de fotos se muestra en la pantalla de una portátil.

design

Compresión de imágenes sin perder calidad: el verdadero conflicto explicado

La "compresión sin pérdida de calidad" solo existe en formatos sin pérdida. El objetivo real es visualmente sin pérdida: aquí está la diferencia honesta y cómo lograrlo deliberadamente.

11 min read


“Talk is cheap. Show me the code.”
― Linus Torvalds

design

Hoja de referencia de sintaxis cron (2026): Lee y crea cualquier expresión de crontab

La sintaxis de cron explicada: el orden de los 5 campos, un modelo para leerlo en 10 segundos, 16 recetas verificadas, la trampa del OR en los días, problemas con el horario de verano y cron vs systemd timers.

10 min read

herramienta para desarrollador regex tester y pattern builder — ilustración original

design

Regex Tester & Pattern Builder: Una guía práctica para crear patrones que sí funcionan

Cómo construir expresiones regulares que realmente funcionan: anclas, cuantificadores, las trampas entre motores y el patrón ReDoS que puede colgar tu servidor. Prueba mientras avanzas.

9 min read

Laptop con código y una planta en una cafetería

design

JSON vs YAML vs TOML: Cuándo elegir cada uno (guía para desarrolladores)

JSON vs YAML vs TOML, decidido: JSON para APIs y datos, YAML para configuración de Kubernetes/CI (cuidado con el problema de Noruega), TOML para configuración explícita de apps como Cargo.toml. Una guía clara de decisión.

9 min read

asequibilidad de préstamos para autos y la regla 20/4/10 — ilustración hero original

finance

Calculadora de Asequibilidad de Préstamos para Autos vs la Regla 20/4/10: ¿Quién te Está Engañando?

Una calculadora de pagos dice que un préstamo promedio de $44,156 es asequible con ingresos medianos. La regla 20/4/10 dice que necesitas $146,000. Aquí están las matemáticas.

8 min read

CSS Gradient Generator Workflow: Create, Check, and Copy

CSS Gradient Generator Workflow: Create, Check, and Copy

Build a CSS gradient you can copy and paste, then validate its syntax and add a practical fallback without installing another tool.

5 min read