Cómo escribir un CHANGELOG

Guía para escribir un archivo CHANGELOG.md siguiendo el estándar Keep a Changelog, con versionado semántico, categorías de cambios y ejemplos completos

Un changelog es un archivo que registra los cambios relevantes de cada versión de un proyecto, ordenados de la más reciente a la más antigua. Se escribe en Markdown, se llama CHANGELOG.md y vive en la raíz del repositorio, junto al README.

Suena trivial, pero es de las pocas cosas que separan un proyecto que la gente puede actualizar con confianza de uno donde cada versión nueva es una lotería. Esta guía cubre el estándar que se usa hoy, cómo relacionarlo con el número de versión y cómo redactar las entradas para que sirvan de algo.

Qué es un changelog y qué no es

Un changelog es un documento para personas. Explica qué ha cambiado en cada versión y qué implica ese cambio para quien usa el proyecto.

Eso lo diferencia de dos cosas con las que se confunde a menudo. No es el historial de Git, que registra cada commit con detalle técnico y está pensado para quien desarrolla. Y no son las notas de la release, que suelen ser un texto promocional centrado en lo llamativo.

La prueba del algodón: si alguien va a actualizar de la versión anterior a la tuya, ¿tu changelog le dice lo que necesita saber antes de hacerlo? Si la respuesta es no, el archivo no está cumpliendo su función.

Por qué no vale con volcar el log de Git

La tentación es obvia: ya tienes el historial, ¿por qué escribirlo otra vez? Porque un log de Git generado automáticamente produce algo así.

- fix typo
- wip
- merge branch feature/auth
- refactor user service
- fix tests

Nada de eso le sirve a quien usa el proyecto. Los commits describen el trabajo de quien programa, no las consecuencias para quien consume. Un changelog útil traduce ese trabajo a efectos observables.

Por eso el consejo estándar es escribirlo a mano, o al menos revisar a mano cualquier borrador generado. Es cinco minutos por versión y es la parte del proyecto con mejor relación entre esfuerzo y utilidad.

Keep a Changelog, el estándar de facto

Existe una convención ampliamente adoptada llamada Keep a Changelog, que define cómo estructurar el archivo. No es un estándar oficial de ningún organismo, pero es lo que espera encontrar cualquiera que abra tu CHANGELOG.md.

La estructura del archivo

El documento empieza con un encabezado de nivel uno y una nota que explica qué convenciones sigue. Después vienen los bloques de versión, del más reciente al más antiguo.

# Changelog

Todos los cambios notables de este proyecto se documentan en este archivo.

El formato sigue Keep a Changelog y el proyecto usa versionado semantico.

## [Sin publicar]

## [1.2.0] - 2026-08-15

### Anadido

- Soporte para exportar a PDF

### Corregido

- El buscador ignoraba los acentos

Cada versión es un encabezado de nivel dos con el número entre corchetes y la fecha en formato AAAA-MM-DD. Los corchetes no son decorativos: permiten definir el número como un enlace de referencia al final del archivo, apuntando a la comparación de versiones en el repositorio.

[1.2.0]: https://github.com/usuario/proyecto/compare/v1.1.0...v1.2.0
[1.1.0]: https://github.com/usuario/proyecto/compare/v1.0.0...v1.1.0

La fecha en formato ISO es importante porque evita la ambigüedad entre el orden británico y el estadounidense. Un 03/04/2026 significa cosas distintas según quién lo lea.

La sección Sin publicar

Arriba del todo, antes de la primera versión, conviene mantener una sección para los cambios que ya están en la rama principal pero todavía no se han publicado.

## [Sin publicar]

### Anadido

- Modo oscuro en el panel de ajustes

Sirve para dos cosas. Quien sigue el proyecto ve lo que viene, y tú acumulas las entradas según las vas haciendo en vez de intentar reconstruirlas el día de la publicación. Cuando llega el momento de publicar, renombras la sección con el número y la fecha, y creas una nueva sección vacía encima.

Las seis categorías de cambios

Dentro de cada versión, los cambios se agrupan en encabezados de nivel tres. La convención define seis categorías y conviene ceñirse a ellas en vez de inventar las tuyas.

CategoríaCuándo se usa
AñadidoFuncionalidades nuevas
CambiadoCambios en funcionalidades que ya existían
ObsoletoFuncionalidades que se eliminarán en el futuro
EliminadoFuncionalidades retiradas en esta versión
CorregidoErrores resueltos
SeguridadVulnerabilidades corregidas

Solo se incluyen las categorías que tengan contenido. Si una versión solo corrige errores, tendrá únicamente el bloque de corregido.

La categoría de obsoleto es la que más se ignora y la más valiosa. Avisar con una versión de antelación de que algo va a desaparecer es la diferencia entre una migración ordenada y un montón de proyectos rotos. La de seguridad merece su propio bloque porque hay gente que solo actualiza cuando ve algo ahí.

Versionado semántico

El changelog y el número de versión son dos caras de lo mismo. El estándar habitual es el versionado semántico, que usa tres números separados por puntos.

MAYOR.MENOR.PARCHE

Cuándo sube cada número

La regla es corta y se puede deducir directamente de las categorías del changelog.

  • MAYOR: cuando hay algún cambio que rompe la compatibilidad. Todo lo que vaya en la categoría de eliminado, y los cambios que alteren un comportamiento del que dependa alguien.
  • MENOR: cuando añades funcionalidad sin romper nada. Es el caso de la categoría de añadido, y también de la de obsoleto, porque marcar algo como obsoleto todavía no lo rompe.
  • PARCHE: cuando solo corriges errores. Las categorías de corregido y de seguridad.

De ahí sale una comprobación muy útil: si tu versión tiene entradas en eliminado pero solo has subido el número menor, algo no cuadra. El changelog te dice qué número te toca.

El caso de las versiones cero

Mientras el primer número es cero, el proyecto se considera en desarrollo inicial y la convención permite romper la compatibilidad en cualquier momento. Publicar la 1.0.0 es el compromiso de dejar de hacerlo a la ligera, no una señal de que el proyecto ya está terminado.

Cómo redactar cada entrada

Aquí es donde se gana o se pierde la utilidad del archivo, y la regla es escribir desde el punto de vista de quien usa el proyecto, no de quien lo programó.

Compara estas dos formas de contar el mismo cambio:

### Cambiado

- Refactorizado el modulo de autenticacion

### Cambiado

- Los tokens de sesion ahora caducan a los 30 dias en vez de a los 7.
  Las sesiones activas se cerraran al actualizar.

La primera describe el trabajo. La segunda describe la consecuencia, que es lo único que le importa a quien va a actualizar.

Algunas costumbres que ayudan:

  • Una línea por cambio, empezando por el elemento afectado y no por el verbo técnico.
  • Menciona el impacto cuando la persona tenga que hacer algo. Si hay que migrar datos o cambiar una configuración, dilo ahí.
  • Enlaza a la incidencia o al pull request cuando aporte contexto, pero sin que el enlace sustituya a la explicación.
  • Evita el detalle interno: qué archivo tocaste o cómo se llama la clase nueva no le sirve a nadie que no esté dentro del proyecto.
  • No lo dejes para el final: escribe la entrada en el mismo momento en que haces el cambio, en la sección de sin publicar.

Dónde colocarlo y cómo enlazarlo

El archivo va en la raíz del repositorio con el nombre CHANGELOG.md en mayúsculas, igual que el README y la licencia. GitHub y el resto de plataformas lo reconocen por ese nombre y lo muestran renderizado.

Desde el README conviene enlazarlo de forma visible, porque es donde la gente lo va a buscar.

Consulta el [CHANGELOG](CHANGELOG.md) para ver los cambios de cada version.

Si publicas el proyecto como paquete, el mismo archivo suele alimentar las notas de cada versión de la plataforma correspondiente, así que escribirlo bien te ahorra hacerlo dos veces. Y si tu proyecto tiene documentación aparte, tiene sentido incluirlo también ahí, como explicamos en cómo documentar un proyecto con Markdown.

Automatizar sin perder la utilidad

Hay herramientas que generan el changelog a partir de los mensajes de commit, siempre que estos sigan una convención estricta con prefijos del tipo feat: o fix:. Funcionan, y en proyectos con mucho movimiento ahorran trabajo real.

El punto a tener en cuenta es que la calidad del resultado nunca supera a la de los mensajes de commit. Si el equipo escribe commits pensando en el changelog, sale bien. Si no, sale un log de Git con otro formato. Un término medio que funciona: genera el borrador de forma automática y dedica cinco minutos a reescribir las entradas antes de publicar. Puedes integrarlo en tu flujo de integración continua, como vemos en automatizar tareas con Markdown.

Un ejemplo completo

Así queda un archivo real con varias versiones, incluyendo un cambio que rompe compatibilidad:

# Changelog

Todos los cambios notables de este proyecto se documentan en este archivo.

## [Sin publicar]

### Anadido

- Exportacion a formato EPUB

## [2.0.0] - 2026-08-20

### Eliminado

- Soporte para la API v1, marcada como obsoleta desde la 1.4.0.
  Migra a la v2 siguiendo la guia de migracion del README.

### Cambiado

- La configuracion pasa de config.json a config.yaml.
  El comando de arranque convierte el archivo antiguo automaticamente.

### Seguridad

- Corregida una vulnerabilidad en la validacion de los tokens de sesion.

## [1.4.0] - 2026-06-10

### Anadido

- Soporte para plantillas personalizadas

### Obsoleto

- La API v1 dejara de funcionar en la version 2.0.0

### Corregido

- Los acentos se mostraban mal al exportar a PDF

[Sin publicar]: https://github.com/usuario/proyecto/compare/v2.0.0...HEAD
[2.0.0]: https://github.com/usuario/proyecto/compare/v1.4.0...v2.0.0
[1.4.0]: https://github.com/usuario/proyecto/compare/v1.3.0...v1.4.0

Fíjate en cómo la entrada de eliminado dice qué hacer, y en que la funcionalidad retirada en la 2.0.0 ya se había anunciado como obsoleta en la 1.4.0. Eso es un changelog haciendo su trabajo.

Siguientes pasos

Ya tienes el criterio. Para pasar a la práctica:

👋 Hola! Soy Edu, me encanta crear cosas y he redactado este tutorial. Si te ha resultado útil, el mayor favor que me podrías hacer es el de compatirlo en Twitter.

para estar al día con mi contenido. 😊