Skip to content

JS API

The writer takes an iterable of parsed commits plus a context and options, and renders changelog text. Three entry functions cover the common output shapes:

import {
writeChangelogString,
writeChangelog,
writeChangelogStream
} from 'conventional-changelog-writer'

See Introduction for the input shape and a first example.

writeChangelogString(commits, context?, options?)

Section titled “writeChangelogString(commits, context?, options?)”

Buffers the whole changelog into a string. Simplest option for small histories:

const changelog = await writeChangelogString(commits, context, options)

writeChangelog(context?, options?, includeDetails?)

Section titled “writeChangelog(context?, options?, includeDetails?)”

Returns an async-generator function that takes commits and yields the changelog one release at a time — for use with stream.pipeline:

import { pipeline } from 'node:stream/promises'
await pipeline(
commitsStream,
writeChangelog(context, options),
async function* (releases) {
for await (const release of releases) {
process.stdout.write(release)
}
}
)

writeChangelogStream(context?, options?, includeDetails?)

Section titled “writeChangelogStream(context?, options?, includeDetails?)”

Returns a Node.js Transform you can pipe commits through:

commitsStream
.pipe(writeChangelogStream(context, options))
.pipe(process.stdout)

The context holds release-wide template variables. Common fields:

FieldTypeDescription
versionstringVersion of the upcoming release (overridden if a commit carries a version).
titlestringOptional release title.
hoststringHost, e.g. https://github.com.
ownerstringRepository owner.
repositorystringRepository name on the host.
repoUrlstringFull repository URL; used as a fallback when host/owner/repository are absent.
commitstringURL keyword for commits (default commits).
issuestringURL keyword for issues (default issues).
linkReferencesbooleanWhether to render links. Auto-enabled when the repository, commit, and issue are known.
datestringRelease date. Defaults to today (UTC), or the key commit’s date.
previousTag, currentTagstringTags used to build the comparison URL.
linkComparebooleanLink the version to a comparison page. Auto-enabled when both tags are set.

Writer options and their defaults, from the Options type:

OptionTypeDefaultDescription
transform(commit, context, options) => Partial<Commit> | null | Promise<…>defaultCommitTransformTransform each commit; the returned object is merged into it. Return null to drop it.
groupBykeyof Commit'type'Commit property to group by. Falsy disables grouping.
commitsSortstring | string[] | Comparator'header'Sort commits within a group.
commitGroupsSortstring | string[] | ComparatorSort the commit groups.
notesSortstring | string[] | Comparator'text'Sort notes within a group.
noteGroupsSortstring | string[] | Comparator'title'Sort the note groups.
generateOnfunction | keyof Commit | nullcommit has a valid semver versionWhen to start a new release block.
reversebooleanfalseTreat upstream commits as chronological instead of reverse-chronological.
ignoreRevertedbooleantrueDrop reverted commits.
doFlushbooleantrueFlush the remaining commits into a final release block.
skip(commit) => booleanReturn true to skip a commit.
template(context) => string | Promise<string>defaultRender a whole release.
headerPartialfunctiondefaultRender the release heading.
preamblePartialfunctiondefaultRender text after the heading.
commitPartialfunctiondefaultRender one commit entry.
footerPartialfunctiondefaultRender the release footer (notes).
finalizeContextfunctionpass-throughLast chance to mutate the context before rendering.
formatDate(date) => stringyyyy-mm-dd (UTC)Format the release date.
debug(message) => voidnoopDebug logger.

Shape the output by overriding options. This maps commit types to friendly section titles and sorts the groups:

import { writeChangelogString } from 'conventional-changelog-writer'
const sections = {
feat: 'Features',
fix: 'Bug Fixes'
}
const changelog = await writeChangelogString(commits, context, {
transform: commit => ({
...commit,
type: sections[commit.type] ?? commit.type
}),
commitGroupsSort: 'title'
})

For deeper control, provide your own template / *Partial render functions, or import the defaults from @conventional-changelog/template and wrap them.

Passing includeDetails: true yields structured objects instead of Markdown strings — one per release:

FieldTypeDescription
logstringRendered Markdown for the release.
keyCommitCommit | nullThe commit that started the release, or null.
for await (const { log, keyCommit } of getStream().pipe(writeChangelogStream(context, options, true))) {
console.log(keyCommit?.version, log.length)
}
ExportDescription
writeChangelogStringRender commits to a string.
writeChangelogAsync-generator function for pipeline.
writeChangelogStreamNode.js Transform stream.
defaultCommitTransformThe default transform (shortens hash and header, formats the date).
transformCommitLower-level helper that applies a transform to a single commit.
formatDateThe default date formatter.

The package also re-exports the building blocks from @conventional-changelog/template — the default template, partial functions, and helpers like heading, link, and list.