npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@api-extractor-tools/change-detector-semantic-release-plugin

v0.1.0-alpha.1

Published

semantic-release plugin that uses change-detector to validate and enhance version bumping

Readme

@api-extractor-tools/change-detector-semantic-release-plugin

npm version

A semantic-release plugin that uses @api-extractor-tools/change-detector to validate and enhance version bumping based on actual API changes in TypeScript declaration files.

Features

  • Version Bump Validation: Ensures that commit-derived version bumps match (or exceed) what the actual API changes require
  • API Change Detection: Analyzes TypeScript .d.ts files to detect breaking changes, new features, and modifications
  • Enhanced Release Notes: Automatically adds detailed API change information to release notes
  • Multiple Modes: Supports validate, override, and advisory modes for different workflows

Installation

npm install @api-extractor-tools/change-detector-semantic-release-plugin --save-dev
# or
pnpm add @api-extractor-tools/change-detector-semantic-release-plugin --save-dev

Usage

Add the plugin to your semantic-release configuration:

{
  "plugins": [
    "@semantic-release/commit-analyzer",
    [
      "@api-extractor-tools/change-detector-semantic-release-plugin",
      {
        "mode": "validate",
        "declarationPath": "./dist/index.d.ts",
        "includeAPIChangesInNotes": true
      }
    ],
    "@semantic-release/release-notes-generator",
    "@semantic-release/npm",
    "@semantic-release/github"
  ]
}

Configuration

| Option | Type | Default | Description | | -------------------------- | ---------------------------------------- | ------------ | ----------------------------------------------------------------------------------------------------- | | mode | 'validate' \| 'override' \| 'advisory' | 'validate' | Operating mode for the plugin | | declarationPath | string | null | Path to the declaration file (relative or absolute). If not provided, uses package.json types field | | apiExtractorConfig | string | null | Path to api-extractor.json config file | | includeAPIChangesInNotes | boolean | true | Whether to add API changes to release notes | | failOnMismatch | boolean | true | Fail release when version bump doesn't match API changes (validate mode only) | | baseRef | string | null | Git ref to use as baseline (defaults to last release tag or main) |

Modes

Validate Mode (Default)

Validates that the commit-derived version bump is sufficient for the detected API changes. Fails the release if:

  • A patch bump is proposed but breaking changes are detected (requires major)
  • A minor bump is proposed but breaking changes are detected (requires major)
{
  "mode": "validate",
  "failOnMismatch": true
}

Use when: You want to enforce consistency between commit messages and actual API changes.

Override Mode

Ignores commit messages and uses the API analysis to determine the version bump automatically.

{
  "mode": "override"
}

Use when: You trust the API analysis more than commit messages and want fully automated versioning.

Advisory Mode

Warns about version bump mismatches but doesn't fail the release. Useful for gradual adoption.

{
  "mode": "advisory"
}

Use when: You're evaluating the plugin or have a gradual migration strategy.

Common Pitfalls

1. Running semantic-release Before Building

Problem:

npm run semantic-release  # Declaration files don't exist yet!

Solution:

{
  "scripts": {
    "release": "npm run build && npx semantic-release"
  }
}

Or in CI:

- run: npm run build
- run: npx semantic-release

2. Incorrect Plugin Order

Problem:

{
  "plugins": [
    "@api-extractor-tools/change-detector-semantic-release-plugin",
    "@semantic-release/commit-analyzer" // ❌ Wrong order!
  ]
}

Solution:

{
  "plugins": [
    "@semantic-release/commit-analyzer",
    "@api-extractor-tools/change-detector-semantic-release-plugin" // ✅ After commit-analyzer
  ]
}

3. Multiple Declaration Files Not Consolidated

Problem: Your package exports from multiple .d.ts files, and the plugin only checks one.

Solution: Use a bundler or API Extractor to create a single consolidated declaration file:

{
  "main": "dist/index.js",
  "types": "dist/index.d.ts" // Single entry point
}

4. Using Shallow Git Clones in CI

Problem: Shallow clones don't include tags/history needed for baseline comparison.

Solution:

- uses: actions/checkout@v4
  with:
    fetch-depth: 0 # Get full git history

5. Not Handling Internal vs. Public APIs

Problem: The plugin detects changes in internal APIs that shouldn't affect versioning.

Solution: Use API Extractor to mark APIs as @internal and exclude them from the public declaration file:

/**
 * Public API
 * @public
 */
export function publicFunction(): void {}

/**
 * Internal implementation detail
 * @internal
 */
export function _internalHelper(): void {} // Won't be in public .d.ts

6. Expecting Implementation Changes to Trigger Bumps

Problem: You changed implementation code but not the types, and no version bump occurs.

Solution: This is by design. Use conventional commits for implementation-only changes:

git commit -m "fix: improve performance of calculation"

Advanced Configuration Examples

Monorepo Setup

For monorepos with multiple packages:

{
  "plugins": [
    "@semantic-release/commit-analyzer",
    [
      "@api-extractor-tools/change-detector-semantic-release-plugin",
      {
        "mode": "validate",
        "declarationPath": "packages/my-package/dist/index.d.ts",
        "includeAPIChangesInNotes": true
      }
    ],
    "@semantic-release/release-notes-generator",
    "@semantic-release/npm"
  ]
}

With API Extractor

If using Microsoft's API Extractor:

{
  "plugins": [
    "@semantic-release/commit-analyzer",
    [
      "@api-extractor-tools/change-detector-semantic-release-plugin",
      {
        "mode": "validate",
        "apiExtractorConfig": "./api-extractor.json",
        "includeAPIChangesInNotes": true
      }
    ],
    "@semantic-release/release-notes-generator",
    "@semantic-release/npm",
    "@semantic-release/github"
  ]
}

Strict Validation for Libraries

For library projects where API stability is critical:

{
  "plugins": [
    "@semantic-release/commit-analyzer",
    [
      "@api-extractor-tools/change-detector-semantic-release-plugin",
      {
        "mode": "validate",
        "failOnMismatch": true,
        "includeAPIChangesInNotes": true
      }
    ],
    "@semantic-release/release-notes-generator",
    [
      "@semantic-release/npm",
      {
        "npmPublish": true
      }
    ]
  ]
}

Gradual Adoption

For projects adopting API-based versioning gradually:

{
  "plugins": [
    "@semantic-release/commit-analyzer",
    [
      "@api-extractor-tools/change-detector-semantic-release-plugin",
      {
        "mode": "advisory",
        "includeAPIChangesInNotes": true,
        "failOnMismatch": false
      }
    ],
    "@semantic-release/release-notes-generator",
    "@semantic-release/npm"
  ]
}

Custom Baseline

To compare against a specific git reference:

{
  "plugins": [
    "@semantic-release/commit-analyzer",
    [
      "@api-extractor-tools/change-detector-semantic-release-plugin",
      {
        "mode": "validate",
        "baseRef": "production",
        "declarationPath": "./dist/index.d.ts"
      }
    ],
    "@semantic-release/release-notes-generator"
  ]
}

Private Packages (No Release Notes)

For private packages where you don't need detailed API notes in GitHub:

{
  "plugins": [
    "@semantic-release/commit-analyzer",
    [
      "@api-extractor-tools/change-detector-semantic-release-plugin",
      {
        "mode": "override",
        "includeAPIChangesInNotes": false
      }
    ],
    "@semantic-release/npm"
  ]
}

Example Output

Validation Failure

╔══════════════════════════════════════════════════════════════════╗
║              API CHANGE VALIDATION FAILED                        ║
╚══════════════════════════════════════════════════════════════════╝

Proposed minor bump is insufficient. API analysis detected major-level changes.

Breaking changes detected:
  • Function oldFunction was removed
  • Required parameter added to authenticate()

To fix this:
  1. Update your commit messages to reflect the major changes
  2. Or set "mode": "override" to use API-detected version
  3. Or set "mode": "advisory" to proceed with warnings only

Enhanced Release Notes

## API Changes

### Breaking Changes

- **function** `oldFunction`: Function oldFunction was removed

### Added Exports

- **function** `function newHelper(): string`
- **interface** `NewInterface`

### Modified Exports

- **function** `authenticate`: Added optional parameter
  - Before: `function authenticate(user: string): Promise<Token>`
  - After: `function authenticate(user: string, options?: AuthOptions): Promise<Token>`

### Summary

- **Added**: 2
- **Removed**: 1
- **Modified**: 1

Programmatic Usage

import {
  analyzeAPIChanges,
  validateVersionBump,
  formatAPIChangesAsMarkdown,
  resolveConfig,
} from '@api-extractor-tools/change-detector-semantic-release-plugin'

// Resolve configuration
const config = resolveConfig({
  declarationPath: './dist/index.d.ts',
})

// Analyze API changes
const analysis = analyzeAPIChanges(process.cwd(), config, {
  gitTag: 'v1.0.0',
  version: '1.0.0',
})

console.log(analysis.recommendedBump) // 'major' | 'minor' | 'patch' | 'none'

// Validate a proposed version bump
const validation = validateVersionBump('minor', analysis, 'validate')
console.log(validation.valid) // true or false
console.log(validation.message)

// Generate release notes
if (analysis.report) {
  const notes = formatAPIChangesAsMarkdown(analysis.report)
  console.log(notes)
}

How It Works

  1. verifyConditions: Checks that declaration files exist and configuration is valid
  2. analyzeCommits: Compares current declaration file against the baseline (last release tag) using change-detector
  3. verifyRelease: Validates that the proposed version bump matches the detected API changes
  4. generateNotes: Appends detailed API change information to the release notes

Requirements

  • Node.js 20+
  • Your package must be built with TypeScript declaration files before running semantic-release
  • A git repository with release tags (for baseline comparison)

Troubleshooting

"Could not find declaration file"

Problem: The plugin can't locate your TypeScript declaration files.

Solutions:

  1. Ensure your package is built before semantic-release runs:

    {
      "scripts": {
        "semantic-release": "npm run build && semantic-release"
      }
    }
  2. Explicitly specify the declaration path:

    {
      "plugins": [
        [
          "@api-extractor-tools/change-detector-semantic-release-plugin",
          {
            "declarationPath": "./dist/index.d.ts"
          }
        ]
      ]
    }
  3. Add the types field to your package.json:

    {
      "types": "./dist/index.d.ts"
    }

Version Bump Mismatch Errors

Problem: Release fails with "API CHANGE VALIDATION FAILED"

Explanation: Your commits suggest a smaller version bump than what the API changes require.

Solutions:

  1. Update your commit messages to reflect the actual changes:

    # For breaking changes:
    git commit -m "feat!: remove deprecated API"
    
    # For new features:
    git commit -m "feat: add new helper function"
    
    # For bug fixes:
    git commit -m "fix: correct return type"
  2. Use override mode to let the plugin determine the version automatically:

    {
      "mode": "override"
    }
  3. Use advisory mode to proceed with warnings:

    {
      "mode": "advisory"
    }

"No baseline found" or New Package Issues

Problem: Plugin reports it can't find a baseline for comparison.

Explanation: This is normal for:

  • Initial releases
  • First time using the plugin
  • Repositories without release tags

Solutions:

  1. For new packages, the plugin will automatically detect this and recommend a minor release in override mode

  2. In validate mode, proceed normally - the plugin won't block new packages

  3. If you have releases but no tags, create tags for past releases:

    git tag v1.0.0 <commit-hash>
    git push --tags

Plugin Not Running During Release

Problem: The plugin doesn't appear to be executing.

Solutions:

  1. Ensure the plugin is listed in the correct order (after @semantic-release/commit-analyzer):

    {
      "plugins": [
        "@semantic-release/commit-analyzer",
        "@api-extractor-tools/change-detector-semantic-release-plugin",
        "@semantic-release/release-notes-generator"
      ]
    }
  2. Check that declaration files exist before the plugin runs

  3. Review semantic-release logs for errors during plugin execution

False Positive Breaking Changes

Problem: The plugin detects breaking changes that you don't consider breaking.

Explanation: The plugin uses strict semantic versioning rules based on TypeScript's type system.

Solutions:

  1. Use advisory mode if your package has different versioning requirements:

    {
      "mode": "advisory"
    }
  2. Consider if the changes are truly non-breaking from a consumer perspective

  3. Use @deprecated JSDoc tags to mark symbols before removing them

CI/CD Integration Issues

Problem: Plugin works locally but fails in CI.

Solutions:

  1. Ensure your build step runs before semantic-release in CI:

    # GitHub Actions example
    - name: Build
      run: npm run build
    - name: Release
      run: npx semantic-release
  2. Verify git history is available (some CI systems use shallow clones):

    - uses: actions/checkout@v4
      with:
        fetch-depth: 0 # Get full history
  3. Ensure tags are available:

    - run: git fetch --tags

FAQ

Q: Can I use this with JavaScript projects?

A: The plugin requires TypeScript declaration files (.d.ts). If you have a JavaScript project with generated declaration files (via JSDoc or manual .d.ts files), it will work.

Q: What happens if I change the implementation but not the types?

A: The plugin only analyzes TypeScript declaration files, so implementation-only changes won't trigger version bumps. Use conventional commits to specify the version bump in these cases.

Q: Can I customize what counts as a breaking change?

A: Not directly. The plugin uses the underlying @api-extractor-tools/change-detector library which follows strict semantic versioning rules. However, you can:

  • Use advisory mode to receive warnings without blocking releases
  • Manually override version bumps in your commit messages
  • Use override mode with post-processing

Q: Does this replace conventional commits?

A: No, it complements them:

  • In validate mode: Conventional commits determine the version, and the plugin validates it
  • In override mode: The plugin determines the version based on API changes, ignoring commits
  • In advisory mode: Conventional commits determine the version, and the plugin provides warnings

Q: What about monorepos?

A: The plugin works in monorepos. Each package is analyzed independently. Ensure:

  • Each package has its own declarationPath configuration
  • semantic-release is configured per-package (or using a tool like semantic-release-monorepo)

Q: Can I use this without semantic-release?

A: Yes! The plugin exports utility functions for programmatic use:

import { analyzeAPIChanges } from '@api-extractor-tools/change-detector-semantic-release-plugin'

const analysis = analyzeAPIChanges(process.cwd(), config, lastRelease)

Q: How do I migrate from conventional commits to API-based versioning?

A: Gradual migration path:

  1. Start with advisory mode to see warnings without breaking your release process
  2. Review and adjust your commit message practices based on warnings
  3. Switch to validate mode once comfortable
  4. Optionally move to override mode for full API-driven versioning

Q: Does the plugin support pre-release versions?

A: The plugin focuses on detecting the release type (major, minor, patch). Pre-release tags are handled by semantic-release's normal flow.

Q: What if my API changes are in multiple files?

A: Currently, the plugin analyzes a single declaration file (typically a bundled/rolled-up .d.ts). For best results:

  • Use API Extractor or a bundler to create a single entry point
  • Configure the declarationPath to point to this bundled file

Related

License

MIT