Skip to content

Structured Changelog

A canonical, deterministic changelog framework with JSON IR and Markdown rendering.

Structured Changelog provides a machine-readable JSON Intermediate Representation (IR) as the source of truth for your changelog, with deterministic Markdown generation for human readability. It supports optional security metadata (CVE, GHSA, SARIF) and SBOM information.

Overview

┌─────────────────┐      ┌─────────────────┐      ┌─────────────────┐
│  CHANGELOG.json │ ───> │    Renderer     │ ───> │  CHANGELOG.md   │
│  (Canonical IR) │      │ (Deterministic) │      │ (Human-Readable)│
└─────────────────┘      └─────────────────┘      └─────────────────┘

Key Principles

  1. JSON IR is canonical — Markdown is derived, not the source of truth
  2. Deterministic rendering — Same input always produces identical output
  3. Keep a Changelog format — Compatible with keepachangelog.com
  4. Semantic Versioning — Follows semver.org conventions
  5. Extensible metadata — Optional security (CVE/GHSA/SARIF) and SBOM fields
  6. Spec + tooling together — Single source of truth for humans and machines

Installation

Homebrew (macOS/Linux)

brew tap grokify/tap
brew install structured-changelog

This installs the schangelog CLI (also available as structured-changelog).

Go Install

go install github.com/grokify/structured-changelog/cmd/schangelog@latest

Go Library

go get github.com/grokify/structured-changelog

Quick Start

Define your changelog in JSON

{
  "irVersion": "1.0",
  "project": "my-project",
  "releases": [
    {
      "version": "1.0.0",
      "date": "2026-01-03",
      "added": [
        { "description": "Initial release with core features" }
      ]
    }
  ]
}

Generate Markdown

package main

import (
    "fmt"

    "github.com/grokify/structured-changelog/changelog"
    "github.com/grokify/structured-changelog/renderer"
)

func main() {
    cl, err := changelog.LoadFile("CHANGELOG.json")
    if err != nil {
        panic(err)
    }
    md := renderer.RenderMarkdown(cl)
    fmt.Println(md)
}

CLI Usage

# Validate a changelog
schangelog validate CHANGELOG.json

# Generate Markdown
schangelog generate CHANGELOG.json -o CHANGELOG.md

# Initialize from git tags
schangelog init --from-tags -o CHANGELOG.json

# Merge changelog files
schangelog merge base.json additions.json -o CHANGELOG.json

# Parse commits for LLM-assisted generation
schangelog parse-commits --since=v1.0.0

Documentation