CommonMark frente a GFM: qué admite cada motor, en una tabla
18 de agosto de 2026 · 35 min de lectura
Pega el mismo archivo en tres herramientas y puedes acabar con tres documentos. Una dibuja una tabla, otra muestra una fila de barras verticales. Una convierte un salto de línea simple en un corte de línea, otra junta las líneas en un párrafo. Nada está roto y nada está mal configurado. Las herramientas hablan dialectos distintos, «Markdown» nombra a la familia entera y no a un miembro concreto, y saber cuál estás escribiendo es la mayor parte de la solución.
Resumen
CommonMark es una especificación con su propia batería de pruebas: resuelve las discusiones sobre
la sintaxis original y se detiene a propósito en un núcleo, sin tablas, sin listas de tareas, sin
tachado y sin autoenlaces de URL sueltas. GFM es esa especificación más exactamente cinco
extensiones con nombre —tablas, elementos de lista de tareas, tachado, autoenlaces, y un filtro que
escapa nueve etiquetas HTML crudas— y es el dialecto que la mayoría de la gente tiene en mente
cuando dice Markdown. Todo lo demás que has visto en un archivo .md —notas al pie, listas de
definiciones, listas de atributos, matemáticas, avisos, cabeceras de metadatos— no está en ninguna
de las dos especificaciones y solo llega hasta donde alcance la lista de extensiones de la siguiente
herramienta. Escribe para el lector más estricto de la cadena, y pruébalo con un archivo de sondeo
en vez de con una suposición.
Tres especificaciones, y los años entre ellas
John Gruber publicó Markdown en 2004: una descripción de sintaxis en una página web, y
Markdown.pl, un script en Perl que convertía esa sintaxis en HTML. La última versión fue la
1.0.1, fechada el 17 de diciembre de 2004 (comprobado en daringfireball.net/projects/markdown, el 8
de septiembre de 2026). La página y el script juntos eran la definición, y allí donde la prosa
callaba —que era a menudo— lo que el script hiciera se convertía en la respuesta.
Eso funciona bien para un blog y resulta doloroso para la segunda implementación. La descripción nunca dice cuántos espacios sangran una lista anidada, qué pasa cuando el énfasis se abre dentro de una palabra, cómo interactúa una lista con la cita en la que está metida, o si un salto forzado sobrevive al final de un párrafo. Cada implementador adivinaba, y las suposiciones diferían. En pocos años había docenas de bibliotecas, todas llamadas Markdown, ninguna de acuerdo sobre los casos incómodos y todas de acuerdo sobre los fáciles. Así que la comparación que la gente busca como commonmark vs markdown es en realidad una comparación entre una especificación y una descripción más un script.
CommonMark, publicado por primera vez en 2014, es esa especificación que faltaba, ya escrita. Define las reglas de análisis con detalle y trae cientos de casos de prueba, cada uno un fragmento de Markdown junto al HTML exacto que debe producir. No existe tal cosa como «casi CommonMark»: una implementación pasa la batería o no la pasa.
GFM abordó el problema desde el otro extremo. GitHub tenía un renderizador con millones de archivos apuntando a él y una lista de añadidos de los que dependían sus usuarios, así que escribió la especificación de GitHub Flavored Markdown como un superconjunto estricto de CommonMark — el mismo documento, con cinco secciones de extensión añadidas. Por eso commonmark vs gfm tiene una respuesta corta: mismo núcleo, cinco añadidos con nombre, ninguna otra diferencia. Todo lo que queda más allá de esos cinco es la extensión de alguien, y las extensiones son donde los archivos dejan de viajar.
Lo que CommonMark de verdad zanjó
Es fácil leer CommonMark como un Markdown más corto por lo que deja fuera. El valor está en lo que fija. Cada uno de estos puntos fue un desacuerdo real entre implementaciones antes de que existiera la especificación, y ahora cada uno se responde señalando un ejemplo numerado.
- La sangría de las listas. Cuánto hay que sangrar una lista hija se define en función de la
columna de contenido del padre, no de un número fijo de espacios. Por eso las marcas
-y1.se comportan distinto cuando anidas debajo de ellas: tienen anchuras diferentes. - Listas sueltas y compactas. Una línea en blanco entre elementos vuelve suelta toda la lista,
lo cual envuelve el texto de cada elemento en
<p>. Una sola línea en blanco perdida cambia el espaciado de una lista que no tocaste — la sorpresa más frecuente de toda la especificación, y una que tiene sus propios comportamientos que merece la pena conocer. - El énfasis. Las reglas de series de delimitadores flanqueantes por la izquierda y por la
derecha sustituyen al viejo «depende» para
palabras_con_guion_bajo,**negrita**pegada, y cualquier mezcla de asteriscos y guiones bajos. - Los bloques de código delimitados. Cercas de comilla invertida y de virgulilla, las reglas de la cerca de cierre, y la cadena de información. La palabra después de la cerca es una etiqueta y nada más: todo conversor la convierte en un nombre de clase y ahí se detiene.
- Los saltos forzados. Dos espacios finales o una barra invertida al final de la línea. Un salto de línea simple es un espacio. Esta es una regla de la especificación, no una preferencia, y es la regla que más herramientas ofrecen la opción de romper.
- Los bloques HTML. Siete tipos distintos, cada uno con sus propias condiciones de inicio y
cierre, por eso un
<div>a veces se traga el Markdown que viene después y a veces no. - Las definiciones de referencia de enlace, las referencias de entidad, la expansión de tabulaciones a cuatro columnas, los separadores temáticos, las cabeceras ATX y setext, y la continuación perezosa de las citas.
CommonMark se detiene a propósito en ese núcleo. Sin tablas, sin notas al pie, sin tachado, sin listas de tareas, sin autoenlazado de URL sueltas. El razonamiento es defendible: el núcleo es lo que todos ya tenían en común, y congelar las discusiones sobre él era el trabajo. La consecuencia es que un analizador estrictamente conforme renderiza tu tabla como un párrafo lleno de barras verticales, en silencio y correctamente.
Lo que añade GFM, regla por regla
La especificación de GFM nombra cinco extensiones. Cuatro añaden sintaxis; una quita algo. Cada una tiene reglas lo bastante específicas como para tropezar con ellas, y los fallos son siempre silenciosos — una tabla que no se reconoce es simplemente texto.
Tablas. Una fila de cabecera, una fila delimitadora, y luego cero o más filas de cuerpo. La
fila delimitadora son guiones con dos puntos opcionales: :--- izquierda, :---: centro, ---:
derecha. La regla con la que la gente tropieza es que la fila de cabecera y la fila delimitadora
tienen que contener el mismo número de celdas; si no coinciden, el bloque no es una tabla en
absoluto y obtienes barras verticales en la página (comprobado en github.github.com/gfm, el 8 de
septiembre de 2026). Las barras verticales inicial y final son opcionales. Las filas de cuerpo con
pocas celdas se rellenan con celdas vacías y las que tienen demasiadas se recortan. Las celdas solo
llevan contenido en línea —sin listas, sin bloques delimitados, sin un segundo párrafo dentro de
una celda— y una barra vertical literal tiene que escribirse \|, incluso dentro de un tramo de
código. La tabla termina en la primera línea en blanco o al empezar otro bloque. La mayor parte de
lo que sale mal con las tablas en una conversión viene de estas tres últimas reglas, y
las tablas merecen su propia lectura.
Elementos de lista de tareas. [ ], [x] o [X] como lo primero del primer párrafo de un
elemento de lista, seguido de un espacio. Tiene que ser un elemento de lista: los mismos corchetes
en una línea sola son corchetes literales. La salida es un <input> de casilla marcado
disabled, por eso una lista de comprobación convertida se ve apagada en el navegador — ese es el
renderizado especificado, no un fallo del conversor. Las vistas de issues y pull requests de GitHub
las vuelven pulsables a través de su propia aplicación, algo que no es parte de la sintaxis.
Tachado. ~~texto~~. Un salto de párrafo termina el tramo, igual que termina el énfasis.
GitHub también renderiza una sola virgulilla, y no todas las implementaciones de GFM lo siguen en
eso, así que escribe dos si el archivo va a ir a cualquier otro sitio.
Autoenlaces. Una URL suelta http://, https:// o www., y una dirección de correo suelta,
se convierten en enlaces sin corchetes angulares. Las reglas son más estrechas de lo que parecen. La
URL tiene que empezar al principio de una línea o seguir a un espacio o a uno de *, _, ~ y
(. La puntuación final se recorta del extremo del enlace en vez de incluirse. Un paréntesis de
cierre se incluye solo si los paréntesis están equilibrados, por eso una URL de Wikipedia que
termina en (disambiguation) normalmente sobrevive y una URL dentro de un paréntesis suele perder
su último carácter. Un guion bajo en cualquier lugar de los dos últimos segmentos del dominio anula
el autoenlace por completo. Los autoenlaces con corchetes angulares, <https://example.com>, son
CommonMark puro y siempre funcionan — la extensión solo cubre la forma suelta.
HTML crudo no permitido. La resta. GFM escapa el < de apertura de nueve nombres de etiqueta
para que lleguen a la página como texto visible en lugar de como marcado: title, textarea,
style, xmp, iframe, noembed, noframes, script y plaintext (comprobado en
github.com/github/cmark-gfm, el 8 de septiembre de 2026). Esta es una regla de seguridad de
renderizado que pertenece a GFM y no a Markdown, y merece la pena ser preciso sobre lo que no es. No
es un depurador. Filtra nueve nombres de etiqueta por lista; no hace nada contra onerror= en una
<img>, nada contra javascript: en un <a href>, y nada contra un <svg> con un manejador
puesto. Si estás convirtiendo un archivo que escribió otra persona,
sigues necesitando un depurador real con lista blanca después
del analizador.
Se cree comúnmente que dos cosas están en GFM y no lo están. Las notas al pie no están en la
especificación, aunque el sitio de GitHub las renderiza. Tampoco los avisos > [!NOTE]. Ambos son
comportamientos de un renderizador concreto, añadidos después de escribirse la especificación, y un
analizador que afirma cumplir GFM no se equivoca al ignorarlos.
Lo que no está en ninguna de las dos especificaciones
Más allá de esas cinco extensiones el terreno deja de ser compartido. Todo lo de abajo es común, útil y no portable — cada uno existe en varias sintaxis, o en una sola herramienta.
- Notas al pie —
[^1]en el texto,[^1]:al final. GitHub las renderiza, Pandoc las renderiza, remark-gfm las renderiza, y un analizador CommonMark puro imprime los corchetes exactamente tal como se escribieron. - Listas de definiciones — un término, y luego líneas que empiezan con
:. Heredadas de PHP Markdown Extra. Pandoc, Python-Markdown, Goldmark y kramdown la tienen; el mundo JavaScript en su mayoría no. - Listas de atributos —
{#mi-id .aviso}después de una cabecera o un tramo, para fijar un id, una clase o un atributo arbitrario. Incorporada en Pandoc y kramdown, una extensión oficial en Python-Markdown, un plugin en markdown-it, y ausente en marked. - Matemáticas —
$...$en línea y$...$en bloque, entregadas a KaTeX o MathJax en la página. Cada implementación lo escribe de forma distinta, y varias necesitan una opción de paso directo para que el analizador deje el TeX en paz en vez de comerse los guiones bajos como énfasis. - Avisos —
> [!NOTE]en GitHub,:::noteen Docusaurus y en varios otros marcos,!!! noteen MkDocs, una lista de atributos{: .note}en Jekyll. Cuatro sintaxis para una sola idea, y ninguna especificación para ninguna de ellas. - Cabeceras de metadatos — un bloque YAML delimitado por
---al principio del archivo. Los generadores de sitios lo eliminan y lo leen como metadatos. Un conversor que nunca ha oído hablar de él lo renderiza como contenido, y el resultado es una línea horizontal seguida de tus metadatos convertidos en una cabecera, porque---bajo una línea de texto es sintaxis de cabecera setext. - Anclas de cabecera — los ids
#titulo-de-seccionque hacen funcionar un índice. Generados en el momento de renderizar por GitHub, por casi todo generador, y por un plugin u opción en la mayoría de las bibliotecas. No es sintaxis en absoluto, y el algoritmo de slug difiere entre herramientas, así que un enlace cruzado escrito a mano puede romperse cuando cambia el renderizador. - Las más pequeñas — abreviaturas, superíndices y subíndices, códigos cortos de emoji como
:tada:, enlaces de wikiPágina, mermaid tratado como diagrama en vez de como bloque de código, y puntuación inteligente que convierte tus comillas en curvas quieras o no.
Comparativa rápida: los dialectos y los motores que los hablan
| Nombre | Mejor para | Capacidad clave | Precio |
|---|---|---|---|
| Markdown original 1.0.1 | Referencia histórica | La página de sintaxis de 2004 más Markdown.pl |
Gratis, licencia de estilo BSD |
| CommonMark | Zanjar una discusión sobre el análisis | Una especificación con una batería de pruebas ejecutable | Gratis, especificación abierta |
| GitHub Flavored Markdown | El objetivo por defecto para cualquier cosa compartida | CommonMark más cinco extensiones con nombre | Gratis, especificación abierta |
| markdown-it (JS) | Corrección con margen para ampliar | Conforme a CommonMark, escapa el HTML crudo por defecto | Gratis, MIT |
| marked (JS) | GFM sin ninguna decisión que tomar | GFM activo por defecto, una llamada de función | Gratis, MIT |
| remark / unified (JS) | Reescribir el documento, no solo renderizarlo | Un AST más remark-gfm y un gran conjunto de plugins | Gratis, MIT |
| Markdown de Pandoc | Documentos que necesitan notas al pie y matemáticas | Extensiones con nombre que activas una por una | Gratis, GPL |
| Python-Markdown | Compilaciones en Python y sitios MkDocs | API de extensión oficial: tablas, notas al pie, attr_list | Gratis, BSD |
| Goldmark (Go) | Programas en Go y sitios Hugo | CommonMark más un conjunto de extensión GFM incluido | Gratis, MIT |
| kramdown (Ruby) | Jekyll y GitHub Pages | Un superconjunto de Markdown con listas de atributos en línea | Gratis, MIT |
| MDX | Sitios de documentación con componentes | JSX dentro de Markdown, compilado en vez de renderizado | Gratis, MIT |
Los dialectos y las implementaciones, uno por uno
Lo que sigue trata solo del dialecto — qué construcciones reconoce cada uno y cómo cambias eso. Cuál elegir como conversor es una comparación distinta, con otros criterios.
Markdown original 1.0.1 — el antepasado, no un objetivo
La página de sintaxis y el script en Perl de Gruber. Sigue siendo la razón por la que un archivo
.md permite HTML crudo en absoluto, y sigue siendo el origen de comportamientos que sobreviven en
herramientas escritas mucho después.
| A favor | En contra |
|---|---|
| La descripción más corta de la sintaxis jamás escrita | Ambigua justo en los puntos donde las implementaciones no se ponen de acuerdo |
| Explica por qué el HTML crudo pasa sin filtrar por defecto | Sin tablas, sin bloques de código delimitados, sin batería de pruebas |
Sigue siendo la base de markdown_strict en Pandoc |
Sin mantenimiento desde la 1.0.1 |
Precio: gratis, licencia de estilo BSD.
Detalles técnicos y funciones
- Solo bloques de código con sangría — el código delimitado llegó con dialectos posteriores
- Las etiquetas HTML a nivel de bloque crudas pasan sin tocar, y el Markdown dentro de ellas no se analiza
- Énfasis, enlaces, imágenes, citas, cabeceras ATX y setext, listas, líneas horizontales
- Ninguna especificación de la sangría de listas anidadas, que es la ambigüedad que todo lo posterior heredó
¿Para quién es? Para nadie, como objetivo. Léela para entender por qué una construcción se
comporta como se comporta, y elige markdown_strict en Pandoc si necesitas saber específicamente
cómo se habría renderizado un archivo en 2004.
CommonMark — el núcleo contra el que se mide todo lo demás
CommonMark es la especificación más cmark, su implementación de referencia en C. Su propósito es
la conformidad, no las funciones, y su contención es la función.
| A favor | En contra |
|---|---|
| Cada caso incómodo tiene un ejemplo numerado y una salida esperada | Sin tablas, listas de tareas, tachado ni autoenlaces sueltos |
| Cientos de casos de prueba, así que la conformidad es un hecho y no una afirmación | Una tabla se renderiza como un párrafo de barras verticales, en silencio |
| Existen implementaciones para casi todos los lenguajes y apuntan a la misma batería | Deliberadamente sin ningún mecanismo de extensión en la propia especificación |
| El suelo más seguro contra el que escribir | La mayoría de los documentos reales necesitan al menos una extensión |
Precio: gratis, especificación abierta; cmark es gratuito con licencia BSD de 2 cláusulas.
Detalles técnicos y funciones
- Define la sangría de las listas relativa a la columna de contenido del padre, terminando la discusión de los espacios
- Las series de delimitadores flanqueantes por la izquierda y por la derecha definen el énfasis con precisión
- Siete tipos de bloque HTML, cada uno con condiciones explícitas de inicio y fin
- Los saltos forzados son dos espacios finales o una barra invertida final; un salto de línea suelto es un espacio
- El HTML crudo pasa sin filtrar por defecto, que es una decisión de la especificación y no una de seguridad
- Entre las implementaciones acompañantes están comrak en Rust, y markdown-it y Goldmark apuntan a la misma batería
¿Para quién es? Para cualquiera que necesite saber qué significa la sintaxis en vez de qué hace una herramienta. Cuando dos renderizadores no están de acuerdo, los ejemplos de la especificación decidien cuál tiene el error — y recurrir a ella es, más a menudo de lo que la gente espera, la jugada correcta.
GitHub Flavored Markdown — el valor por defecto práctico
GFM es CommonMark más tablas, listas de tareas, tachado, autoenlaces y el filtro de HTML crudo. Es lo que renderiza un README, y lo que copiaron la mayoría de los rastreadores de issues y las herramientas de chat.
| A favor | En contra |
|---|---|
| Una especificación escrita, no solo el comportamiento de un renderizador | Sigue sin notas al pie, listas de definiciones, matemáticas ni atributos |
| Cubre las construcciones que de verdad usa la mayoría de los documentos | El filtro de etiquetas se confunde a menudo con un depurador |
| Ampliamente implementado, así que un archivo GFM suele viajar bien | El sitio de GitHub renderiza cosas que la especificación no define |
| Un superconjunto estricto de CommonMark, así que nada del núcleo cambia | Las reglas de autoenlace suelto son más exigentes de lo que parecen |
Precio: gratis, especificación abierta.
Detalles técnicos y funciones
- Tablas con alineación por columna, solo contenido en línea, y se exige una fila delimitadora que coincida
- Elementos de lista de tareas renderizados como entradas de casilla
disabled - Tachado con
~~; GitHub también acepta una sola virgulilla - Autoenlaces de URL y correo sueltos, con reglas de puntuación final y de paréntesis equilibrados
- Nueve nombres de etiqueta HTML crudos escapados en vez de pasados sin filtrar
- Las notas al pie y los avisos
> [!NOTE]funcionan en GitHub y no están en la especificación
¿Para quién es? Para casi todo el mundo, en casi todo archivo compartido. Si un documento tiene que renderizarse en GitHub, en un sitio de documentación y como HTML convertido, GFM es la intersección que los tres entienden.
markdown-it — CommonMark primero, extensiones a demanda
Un analizador de JavaScript que sigue la especificación CommonMark y añade una pequeña cantidad encima. Su propio resumen es que «añade extensiones de sintaxis y azúcar (autoenlazado de URL, tipografía)» (comprobado en github.com/markdown-it/markdown-it, el 8 de septiembre de 2026).
| A favor | En contra |
|---|---|
Pasa la batería de CommonMark, y trae un preajuste commonmark estricto |
Las listas de tareas y las notas al pie necesitan plugins |
| Escapa el HTML crudo por defecto, así que el comportamiento seguro es el predeterminado | La calidad de los plugins varía en el ecosistema |
| Las reglas se pueden añadir, sustituir o reordenar a nivel de bloque y en línea | El autoenlazado está apagado hasta que lo activas |
Precio: gratis, licencia MIT.
Detalles técnicos y funciones
- Tres preajustes:
commonmarkpara conformidad estricta,default, yzeropara construir desde cero - Las tablas y el tachado están activos en el preajuste por defecto;
linkifyybreaksestán apagados html: falsepor defecto — el HTML crudo en el origen se escapa, no se pasa sin filtrar- Los plugins cubren notas al pie, contenedores para avisos, atributos, anclas, listas de tareas y matemáticas
- La superficie de plugins está documentada, así que se puede escribir una extensión en vez de buscarla
¿Para quién es? Para equipos que quieren la especificación seguida por defecto y cada extensión activada de forma deliberada. Es también el dialecto que hereda buena parte de las herramientas, la vista previa de Markdown incorporada de VS Code entre ellas.
marked — GFM sin ninguna decisión que tomar
Un analizador y compilador de JavaScript pequeño cuyo dialecto por defecto ya es el que la mayoría de la gente quiere.
| A favor | En contra |
|---|---|
| GFM está activo por defecto: tablas, tachado, listas de tareas, autoenlaces | Sin ecosistema de plugins que valga la pena mencionar; las extensiones las escribes tú |
| Una función, un objeto de opciones | El HTML crudo pasa sin filtrar, por diseño |
| Corre en el navegador y en Node | Las notas al pie, las listas de definiciones y las matemáticas no están disponibles |
Precio: gratis, licencia MIT.
Detalles técnicos y funciones
gfm: truepor defecto;breaks: falsepor defecto, así que un salto de línea simple es un espaciobreaks: truereproduce el comportamiento de las cajas de comentarios de GitHub en vez del de sus README- Un lexer que puedes llamar por separado para inspeccionar tokens en vez de HTML
- Renderizadores personalizados sustituyen cómo se emite cualquier tipo de nodo, que es cómo se hacen la mayoría de las extensiones
- Sin depuración: la respuesta documentada es pasar la salida por DOMPurify
¿Para quién es? Para cualquiera cuyo dialecto objetivo sea GFM llano y que no necesite nada más
allá. Es el camino más corto de un archivo GFM a HTML con forma de GFM, y la razón de que tanto
software se comporte como GitHub con breaks mal puesto.
remark y unified — el dialecto como lista de plugins
remark analiza Markdown en un árbol de sintaxis abstracto. El dialecto no es un ajuste; es qué extensiones añadiste al proceso.
| A favor | En contra |
|---|---|
| remark-gfm cubre las cinco extensiones de GFM, más notas al pie | La opción más pesada de aquí, por un margen amplio |
| Las cabeceras de metadatos, las matemáticas y las directivas tienen cada una un plugin de primera clase | El proceso de unified exige un aprendizaje real |
| El HTML crudo se descarta salvo que lo permitas explícitamente | Cada extensión es una dependencia que mantener al día |
Precio: gratis, licencia MIT.
Detalles técnicos y funciones
- mdast para Markdown, hast para HTML, con plugins para moverse entre los dos
- remark-gfm añade tablas, listas de tareas, tachado, autoenlaces y notas al pie juntos
- remark-frontmatter analiza la cabecera YAML en vez de renderizarla como una cabecera de texto
- remark-directive da contenedores
:::note, que es como se implementan la mayoría de las sintaxis de aviso - Pasar HTML crudo sin filtrar exige
allowDangerousHtml, así que la opción insegura es explícita
¿Para quién es? Para equipos que necesitan un dialecto que nadie ofrece — GFM más notas al pie más directivas más una regla propia sobre el texto de los enlaces— y que están dispuestos a montarlo y mantenerlo.
El Markdown de Pandoc — un dialecto con un panel de interruptores
Pandoc lee varios dialectos de Markdown y el suyo propio, extendido, y cada construcción es una extensión con nombre que puedes activar o desactivar individualmente.
| A favor | En contra |
|---|---|
| Notas al pie, listas de definiciones, atributos y matemáticas están incorporados | Su dialecto no es lo que renderiza GitHub, lo cual sorprende a la gente |
| Varias sintaxis de tabla, incluidas tablas de rejilla con celdas de varias líneas | Los nombres de las extensiones son un vocabulario que aprender |
| Los dialectos de lectura y escritura se eligen por separado | El HTML crudo pasa sin ninguna depuración |
markdown_strict, commonmark, gfm y commonmark_x están todos disponibles |
Exige instalación y una terminal |
Precio: gratis, licencia GPL.
Detalles técnicos y funciones
- Dialectos elegidos por nombre:
markdown,markdown_strict,markdown_phpextra,markdown_mmd,commonmark,commonmark_x,gfm - Extensiones activadas con
+nombrey-nombresobre el formato, por ejemplogfm+footnotes - Sintaxis de atributos
{#id .clase clave=valor}en cabeceras, bloques de código, enlaces e imágenes tex_math_dollarspara matemáticas,fenced_divspara contenedores al estilo aviso,definition_lists,footnotes- Las tablas de rejilla y de varias líneas llevan contenido de bloque dentro de las celdas, algo que las tablas de barras verticales no pueden
¿Para quién es? Para cualquiera que escriba documentos y no páginas: algo con notas al pie,
citas, ecuaciones o un formato de salida distinto de HTML. Recurre a gfm explícitamente cuando el
archivo también tenga que renderizarse en GitHub, porque el dialecto propio de Pandoc acepta sin
problema sintaxis que GitHub no puede dibujar.
Python-Markdown — extensiones como API
La implementación en Python de más larga trayectoria. Su dialecto base está más cerca del Markdown original que de CommonMark, y su API de extensión es sobre lo que se construye buena parte de las herramientas de documentación.
| A favor | En contra |
|---|---|
| Extensiones oficiales para tablas, notas al pie, listas de definiciones y listas de atributos | No es conforme con CommonMark en todos los detalles |
md_in_html analiza Markdown dentro de bloques HTML crudos, algo que la mayoría de los analizadores no hace |
Las listas de tareas y el tachado necesitan extensiones de terceros |
La extensión admonition es la implementación de referencia de !!! note |
Las diferencias con GFM aparecen en casos límite de listas y énfasis |
Precio: gratis, licencia BSD.
Detalles técnicos y funciones
- El paquete
extraagrupa tablas, notas al pie, listas de definiciones, abreviaturas, listas de atributos, código delimitado ymd_in_html tocgenera ids de cabecera y un índice;smartyhace puntuación inteligentenl2brconvierte los saltos de línea simples en<br>, el mismo interruptor que otras herramientas llamanbreaksmetalee una cabecera de metadatos, y MkDocs gestiona la cabecera de metadatos YAML por encima- El tachado, las listas de tareas y las matemáticas
$...$vienen de las PyMdown Extensions de terceros
¿Para quién es? Para scripts de compilación en Python, y para cualquiera que amplíe MkDocs, donde ya es el motor. Sé deliberado con qué extensiones activas: el dialecto es exactamente la lista de tu archivo de configuración, y un archivo escrito contra una lista más completa perderá cosas en silencio.
Goldmark — CommonMark con un interruptor de GFM
Un analizador conforme con CommonMark en Go, y el motor dentro de Hugo. Sus extensiones son valores de Go que compones en vez de cadenas que configuras.
| A favor | En contra |
|---|---|
Conforme con CommonMark, con un único paquete extension.GFM para las cuatro adiciones de GFM |
Solo Go |
| Listas de definiciones, notas al pie y tipografía inteligente vienen de fábrica | Menos extensiones ya hechas que en el ecosistema JavaScript |
| El comportamiento de atributos y de paso directo es explícito en vez de implícito | Algunas decisiones de dialecto llegan a través de la configuración de Hugo, no de la de Goldmark |
Precio: gratis, licencia MIT.
Detalles técnicos y funciones
extension.GFMagrupa Table, Strikethrough, Linkify y TaskList (comprobado en github.com/yuin/goldmark, el 8 de septiembre de 2026)extension.DefinitionListyextension.Footnoteimplementan las sintaxis de PHP Markdown Extrahtml.WithHardWraps()renderiza un salto de línea como<br>, la misma opción con un tercer nombrehtml.WithUnsafe()es obligatorio antes de que el HTML crudo pase sin filtrar, así que el escapado es lo predeterminado- Hugo añade encima ganchos de renderizado y su propia configuración, que es donde de verdad viven la mayoría de las dudas de dialecto en Hugo
¿Para quién es? Para programas en Go, y para usuarios de Hugo que intentan averiguar por qué una construcción se renderiza en GitHub y no en su sitio. La respuesta suele ser una extensión que está disponible y no activada.
kramdown — un superconjunto, no un dialecto de CommonMark
Un conversor superconjunto de Markdown en Ruby puro, y el motor por defecto de Jekyll. Tiene su propia sintaxis para varias cosas que las demás herramientas hacen de forma distinta, lo cual es una ventaja real dentro de Jekyll y un problema real fuera de él.
| A favor | En contra |
|---|---|
Listas de atributos en línea — {: .aviso} — en casi cualquier bloque |
No es conforme con CommonMark, y no pretende serlo |
| Listas de definiciones, notas al pie, abreviaturas y matemáticas incorporadas | Sin listas de tareas ni tachado en la sintaxis principal |
| Las tablas admiten una fila de cabecera y una de pie separadoras | Su propia sintaxis no sobrevive a ser leída por otra herramienta |
| Ya instalado si usas Jekyll o GitHub Pages | La gestión de saltos de línea es configurable y no es la predeterminada de CommonMark |
Precio: gratis, licencia MIT (comprobado en github.com/gettalong/kramdown, el 8 de septiembre de 2026).
Detalles técnicos y funciones
- Escrito en Ruby, sin dependencias obligatorias para el analizador de Markdown
- Las listas de atributos en línea fijan ids, clases y atributos arbitrarios sin bajar a HTML
- Las matemáticas
$...$, las notas al pie y las definiciones de abreviatura son sintaxis principal en vez de plugins - Hay disponible un analizador GFM independiente y es lo que usa GitHub Pages, que no es lo mismo que el dialecto propio de kramdown
- Convierte a HTML, LaTeX y de vuelta a kramdown
¿Para quién es? Para sitios Jekyll, y solo para contenido que se queda en ellos. Si una página escrita en kramdown tiene que leerse en cualquier otro sitio, sus listas de atributos se vuelven llaves visibles.
MDX — un lenguaje distinto con una superficie familiar
MDX pone componentes JSX dentro de Markdown. Se compila a un componente en vez de renderizarse a HTML, y está construido sobre remark, así que la mitad Markdown es el dialecto de remark.
| A favor | En contra |
|---|---|
| Un componente de React en medio de un documento, con props | No es Markdown: ninguna herramienta de Markdown normal puede leerlo |
| La mitad Markdown es CommonMark más los plugins de remark que añadas | Necesita un paso de compilación y un marco de JavaScript |
| Da vida a sitios de documentación donde la prosa y los ejemplos interactivos se mezclan | Un < o un { suelto en la prosa se convierte en un error de sintaxis |
Precio: gratis, licencia MIT.
Detalles técnicos y funciones
- Se compila a JavaScript, así que la salida es un componente y no un archivo HTML
- Usa remark para Markdown y puede tomar remark-gfm y el resto del conjunto de plugins
- Las llaves son expresiones, lo cual significa que una
{literal en la prosa hay que escaparla - Las cabeceras de metadatos necesitan un plugin, como en todos los demás sitios
¿Para quién es? Para sitios de documentación que necesitan ejemplos vivos dentro de la prosa, y para nadie que necesite que el archivo sea portable. Un archivo MDX es código fuente que se parece a un documento.
Funciones frente a implementaciones
Lee hacia abajo la columna de una herramienta, y a lo ancho la fila de una función. «Plugin» significa disponible y no incorporado; «extensión» significa que viene con el proyecto y está apagada hasta activarla; «opción» significa un booleano en algún lugar de la configuración.
| Función | CommonMark | GFM | markdown-it | marked | remark | Pandoc | Python-Markdown | Goldmark | kramdown |
|---|---|---|---|---|---|---|---|---|---|
| Tablas | No | Sí | Activa por defecto | Activa por defecto | remark-gfm | Incorporado, varias sintaxis | Extensión tables |
extension.Table |
Incorporado |
| Elementos de lista de tareas | No | Sí | Plugin | Activo por defecto | remark-gfm | Extensión task_lists |
Extensión de terceros | extension.TaskList |
No |
| Tachado | No | Sí | Activo por defecto | Activo por defecto | remark-gfm | Extensión strikeout |
Extensión de terceros | extension.Strikethrough |
No |
| Autoenlaces de URL suelta | No | Sí | Opción linkify |
Activo por defecto | remark-gfm | autolink_bare_uris |
Extensión de terceros | extension.Linkify |
No |
| HTML crudo por defecto | Pasa sin filtrar | Nueve etiquetas escapadas | Escapado | Pasa sin filtrar | Se descarta salvo permiso | Pasa sin filtrar | Pasa sin filtrar | Escapado salvo modo inseguro | Pasa sin filtrar |
| Notas al pie | No | No en la especificación; GitHub las renderiza | Plugin | No | remark-gfm | Extensión footnotes |
Extensión footnotes |
extension.Footnote |
Incorporado |
| Listas de definiciones | No | No | Plugin | No | Plugin | definition_lists |
Extensión def_list |
extension.DefinitionList |
Incorporado |
| Listas de atributos | No | No | Plugin | No | Plugin | Incorporado | Extensión attr_list |
De terceros | Incorporado |
| Matemáticas | No | No | Plugin | No | remark-math | tex_math_dollars |
Extensión de terceros | Paso directo o de terceros | Incorporado |
| Contenedores de aviso | No | No | Plugin | No | remark-directive | fenced_divs |
Extensión admonition |
De terceros | Listas de atributos |
| Cabeceras de metadatos | No | No | Plugin | No | remark-frontmatter | Incorporado para su propio formato | Extensión meta |
Gestionado por Hugo | Gestionado por Jekyll |
| Ids de cabecera | No | Añadidos por GitHub al renderizar | Plugin | Extensión | Plugin | Incorporado | Extensión toc |
De terceros | Incorporado |
Salto de línea como <br> |
No | No | Opción breaks |
Opción breaks |
remark-breaks | hard_line_breaks |
Extensión nl2br |
WithHardWraps |
Opción |
Dos patrones de esa tabla valen más que las celdas sueltas. El primero es que las herramientas JavaScript no están de acuerdo sobre todo en los valores por defecto, no en las capacidades: markdown-it y marked pueden renderizar el mismo archivo GFM, pero de fábrica una escapa tu HTML crudo y la otra no. El segundo es que las herramientas con la sintaxis más rica —Pandoc, Python-Markdown, kramdown— son las cuyos archivos viajan peor, porque la riqueza está toda en extensiones que nada más implementa.
Cómo saber qué dialecto habla una herramienta
No leas la documentación. Guarda un archivo de sondeo, pégalo, y lee lo que sale.
| Feature | Renders |
| --- | --- |
| tables | yes? |
- [x] a checkbox
- [ ] or literal brackets
~~Strikethrough~~ and a bare URL: https://example.com
Term
: A definition, or a paragraph starting with a colon.
A footnote reference.[^1]
Heading with an attribute
{: .probe}
Line one
line two
[^1]: Only some tools render this.
Nueve respuestas de un solo pegado, en el orden que importa. Una tabla dibujada, casillas, texto
tachado y un enlace vivo cubren las cuatro extensiones de sintaxis de GFM — si aparecen las cuatro,
tienes al menos GFM. Una definición sangrada significa que la herramienta va más allá de GFM, hacia
el terreno de PHP Markdown Extra. Una nota al pie renderizada significa lo mismo. Unas llaves
visibles {: .probe} significan sin listas de atributos, que es la mayoría de las herramientas. Y
si «line two» queda en su propia línea, breaks está activado, algo que conviene saber antes de
escribir diez páginas sobre la suposición equivocada.
Añade un $x^2$ y una línea > [!NOTE] si te importan las matemáticas o los avisos. La gracia del
archivo es que tarda diez segundos y sustituye a una tarde de suposiciones.
Dónde falla GFM — la opción obvia — y qué cuesta
GFM es el valor por defecto correcto, y merece la pena ser honesto sobre los cuatro sitios donde se queda corto.
No tiene notas al pie, y tú tampoco. GitHub renderiza notas al pie, así que la gente las
escribe, y no están en la especificación. Un analizador GFM que ignora [^1] es conforme. Si tu
documento de verdad necesita notas al pie, has salido de GFM aunque no fuera tu intención, y el
coste es que tu archivo ahora depende de la lista de extensiones de una herramienta concreta en vez
de una especificación — qué herramientas renderizan la sintaxis de notas al pie y cuáles imprimen los corchetes
es la lista a comprobar antes de escribir cien notas.
No tiene atributos, así que dar estilo significa HTML crudo. No hay forma en GFM de poner una
clase en un párrafo. O bajas a un <div> —lo cual te deja a merced de lo que el renderizador haga
con el HTML crudo, y del filtro de etiquetas si es un renderizador GFM— o aceptas el estilo por
defecto. Pandoc y kramdown resolvieron esto hace años, y sus soluciones no viajan.
El filtro de etiquetas no es seguridad. Nueve nombres de etiqueta escapados son una lista, no
una política. Cualquiera que convierta Markdown de un tercero pensando que la conformidad con GFM
le cubre está a un <img onerror=> de descubrir lo contrario. La depuración ocurre después del
análisis, contra una lista blanca, y es un trabajo aparte de elegir un dialecto.
La cuestión de los saltos no tiene una respuesta correcta. Las cajas de comentarios de GitHub
convierten un salto de línea simple en un <br>; la especificación dice que un salto de línea
simple es un espacio; el renderizado de README sigue la especificación. Así que el mismo texto puede
renderizarse de dos formas en el mismo sitio web, y cada herramienta posterior tiene que elegir una.
TransformPipe convierte con GFM activo y breaks apagado, lo cual coincide con la especificación y
con el renderizado de README en vez de con la caja de comentarios, porque un documento está más
cerca de un README que de un comentario. Sea lo que elija una herramienta, los párrafos de alguien
salen mal, y es el problema de dialecto más reportado que existe.
El coste de los cuatro juntos es que «GFM» te dice qué se va a renderizar y no qué se va a ver bien. Es un suelo, no un acabado.
Cómo elegir un dialecto
- Escribe para el lector más estricto de la cadena. Si un archivo tiene que renderizarse en GitHub, en un sitio de documentación y como HTML convertido, usa solo lo que los tres admitan, porque el analizador más débil decide lo que ve el lector y no te avisará.
- Elige el dialecto antes que la herramienta, no después. Decidir que necesitas notas al pie y matemáticas te dice que instales Pandoc; decidir que necesitas que se renderice un README te dice que GFM basta. Hacerlo al revés significa descubrir el límite a mitad de un documento.
- Mantén cada extensión cerca de la herramienta que la posee. Las cabeceras de metadatos pertenecen a un repositorio que lee un generador, no a un archivo que le entregas a un conversor que lo va a renderizar como una cabecera de texto. Una lista de atributos pertenece al sitio Jekyll, no al archivo que envías por correo.
- Trata los valores por defecto como parte del dialecto. Dos bibliotecas pueden afirmar ambas que hacen GFM y diferir en el HTML crudo, el autoenlazado y los saltos de línea, lo cual son tres ocasiones para que un archivo se renderice de forma distinta sin que nadie haya cambiado una palabra.
- Convierte un archivo representativo antes de comprometerte. No un archivo de hola-mundo: el que tiene la tabla, la lista de comprobación, la URL larga entre paréntesis y la nota al pie. Diez segundos de sondeo ganan a una reescritura, y es la única forma de ver un fallo silencioso mientras todavía es barato.
Conclusión
CommonMark es el núcleo, GFM es el núcleo más cinco extensiones con nombre, y todo lo demás que
alguna vez escribiste en un archivo .md es la extensión de alguien que se detiene en el borde de
su herramienta. Ese es el mapa completo, y basta para predecir casi cualquier diferencia de
renderizado que vayas a encontrar. Escribe GFM por defecto, recurre a Pandoc cuando el documento
necesite notas al pie o ecuaciones, mantén las cabeceras de metadatos y las listas de atributos en
los proyectos que las entienden, y sondea antes de comprometerte. Si GFM es donde acabas,
convertirlo a HTML en el navegador te mostrará exactamente en qué se convirtió cada
construcción — el origen HTML está ahí mismo junto a la vista previa, así que puedes comprobar la
tabla en vez de confiar en que salga bien.
Preguntas frecuentes
¿Cuál es la diferencia entre CommonMark y GFM?
GFM es la especificación CommonMark más cinco extensiones con nombre: tablas, elementos de lista de tareas, tachado, autoenlaces de URL suelta, y un filtro que escapa nueve nombres de etiqueta HTML crudos. Las reglas de análisis del núcleo son idénticas, porque GFM se define como un superconjunto estricto. Cualquier otra diferencia entre dos renderizadores no es una diferencia entre CommonMark y GFM — es una extensión que uno tiene y el otro no.
¿Es GFM un superconjunto de CommonMark?
Sí, y la especificación lo dice explícitamente. Todo documento CommonMark válido es un documento GFM válido que se renderiza igual, con la única excepción de las nueve etiquetas HTML crudas filtradas, que GFM escapa y CommonMark deja pasar. Por eso escribir CommonMark puro es la forma más segura de hacer un archivo portable.
¿CommonMark admite tablas?
No. Las tablas no están en la especificación de CommonMark, y un analizador estrictamente conforme renderiza una tabla de barras verticales como un párrafo normal que contiene esos caracteres. El fallo es silencioso, así que si una tabla salió como texto, tu analizador probablemente está haciendo exactamente lo que se le pidió. Las tablas llegan con GFM o con una extensión específica de una herramienta.
¿Las notas al pie son parte de GitHub Flavored Markdown?
No en la especificación, a pesar de que el propio sitio de GitHub las renderiza. Las notas al pie son una extensión que Pandoc, remark-gfm, Python-Markdown, Goldmark y kramdown implementan todos de forma parecida, y que un analizador GFM llano tiene derecho a ignorar. Si tu documento las necesita, elige una herramienta por ese requisito y no por la conformidad con GFM.
¿Por qué mi Markdown se renderiza distinto en GitHub y en mi conversor?
Tres causas habituales, por orden de probabilidad. El ajuste de saltos de línea: las cajas de
comentarios de GitHub tratan un salto de línea simple como un <br> y la especificación no. Una
extensión: las notas al pie, las cabeceras de metadatos, los avisos y las matemáticas se renderizan
todos en GitHub o en un generador y no están en ninguna especificación. O una construcción que no es
del todo válida —una tabla cuya fila delimitadora tiene el número equivocado de celdas, por
ejemplo—, de la que GitHub y tu conversor pueden recuperarse de formas distintas.
¿En qué dialecto de Markdown debería escribir?
En GFM, salvo que algo te obligue a salir de él. Está especificado, ampliamente implementado, y cubre tablas, listas de comprobación y tachado, que es la mayor parte de lo que usa un documento real. Pasa al dialecto de Pandoc cuando necesites notas al pie, listas de definiciones o ecuaciones, y acepta que el archivo queda entonces atado a Pandoc.
¿Qué hace un conversor de Markdown con la cabecera de metadatos YAML?
Depende por completo de si la herramienta ha oído hablar de ella, porque las cabeceras de metadatos no están en ninguna de las dos especificaciones. Un generador la elimina y la lee como metadatos; un conversor llano la renderiza como contenido, lo cual produce una línea horizontal seguida de tus metadatos convertidos en una cabecera setext. Si le estás entregando archivos a un conversor, o quitas primero la cabecera o eliges una herramienta con una opción para cabeceras de metadatos.