FerrFlow supports four config file formats, searched in this order:

  1. ferrflow.json
  2. ferrflow.json5
  3. ferrflow.toml
  4. .ferrflow (JSON)

If no config file is found, FerrFlow auto-detects common version files in the current directory.

Config formats

JSON

{
  "$schema": "https://ferrflow.com/schema/ferrflow.json",
  "workspace": {
    "tagTemplate": "v{version}"
  },
  "package": [
    {
      "name": "my-app",
      "path": ".",
      "changelog": "CHANGELOG.md",
      "versionedFiles": [
        { "path": "Cargo.toml", "format": "toml" }
      ]
    }
  ]
}

TOML

[workspace]
tag_template = "v{version}"

[[package]] name = "my-app" path = "." changelog = "CHANGELOG.md"

[[package.versioned_files]] path = "Cargo.toml" format = "toml"

JSON5

{
  $schema: "https://ferrflow.com/schema/ferrflow.json",
  workspace: {
    tagTemplate: "v{version}",
  },
  package: [
    {
      name: "my-app",
      path: ".",
      changelog: "CHANGELOG.md",
      versionedFiles: [
        { path: "Cargo.toml", format: "toml" },
      ],
    },
  ],
}

YAML

workspace:
  tagTemplate: "v{version}"

package:

  • name: my-app path: "." changelog: CHANGELOG.md versionedFiles:
    • path: Cargo.toml format: toml

workspace

Global settings that apply to all packages.

Field Type Default Description
remote string "origin" Git remote to push to
branch string auto-detected Branch to push to (detected from remote HEAD)
tagTemplate string "v{version}" or "{name}@v{version}" Tag naming pattern. Uses {version} and {name} placeholders. Defaults to v{version} for single-package repos and {name}@v{version} for monorepos.
versioning string "semver" Default versioning strategy for all packages
releaseCommitMode string "commit" How to handle the release commit: "commit", "pr", or "none"
skipCi boolean depends on mode Add [skip ci] to release commits. Defaults to true when mode is "commit", false otherwise.
autoMergeReleases boolean true Enable auto-merge on release PRs (only applies when mode is "pr")
recoverMissedReleases boolean false When enabled, if FerrFlow finds unreleased commits spanning multiple version bumps, it creates all intermediate releases instead of jumping to the latest version
telemetry boolean true Send anonymous usage telemetry

Tag template

The tagTemplate field controls how git tags are named. Available placeholders:

Placeholder Description
{version} The version number (e.g. 1.2.3)
{name} The package name

JSON

{
  "workspace": {
    "tagTemplate": "v{version}"
  }
}

TOML

[workspace]
tag_template = "v{version}"

JSON5

{
  workspace: {
    tagTemplate: "v{version}",
  },
}

YAML

workspace:
  tagTemplate: "v{version}"

For monorepos, use {name} to namespace tags per package:

JSON

{
  "workspace": {
    "tagTemplate": "{name}@v{version}"
  }
}

TOML

[workspace]
tag_template = "{name}@v{version}"

JSON5

{
  workspace: {
    tagTemplate: "{name}@v{version}",
  },
}

YAML

workspace:
  tagTemplate: "{name}@v{version}"

Release commit mode

Controls how FerrFlow handles the commit that updates version files and changelogs.

Mode Behavior
"commit" Commits directly to the current branch and pushes (default)
"pr" Creates a release/ branch and opens a pull request
"none" Only creates tags and releases, does not commit file changes

JSON

{
  "workspace": {
    "releaseCommitMode": "pr",
    "autoMergeReleases": true
  }
}

TOML

[workspace]
release_commit_mode = "pr"
auto_merge_releases = true

JSON5

{
  workspace: {
    releaseCommitMode: "pr",
    autoMergeReleases: true,
  },
}

YAML

workspace:
  releaseCommitMode: pr
  autoMergeReleases: true

Versioning strategies

FerrFlow supports multiple versioning strategies, configurable at workspace or package level.

Strategy Format Example progression
semver MAJOR.MINOR.PATCH 1.2.31.3.02.0.0
calver YYYY.MM.PATCH 2026.03.02026.03.12026.04.0
calver-short YY.MM.PATCH 26.03.026.03.1
calver-seq YYYY.MM.SEQ 2026.03.12026.03.2
sequential N 123
zerover 0.MINOR.PATCH 0.1.00.2.0 (never reaches 1.0)

JSON

{
  "workspace": {
    "versioning": "calver"
  }
}

TOML

[workspace]
versioning = "calver"

JSON5

{
  workspace: {
    versioning: "calver",
  },
}

YAML

workspace:
  versioning: calver

package

Defines a package to version. You can have one or many.

Field Required Default Description
name yes Package identifier, used in git tag prefix
path yes Relative path to the package directory
changelog no {path}/CHANGELOG.md Path to the changelog file
sharedPaths no [] Paths that trigger this package when changed
versioning no inherited from workspace Override versioning strategy for this package
tagTemplate no inherited from workspace Override tag template for this package

versionedFiles

Files where the version number should be updated.

JSON

{
  "package": [
    {
      "name": "my-app",
      "path": ".",
      "versionedFiles": [
        { "path": "Cargo.toml", "format": "toml" },
        { "path": "npm/package.json", "format": "json" }
      ]
    }
  ]
}

TOML

[[package]]
name = "my-app"
path = "."

[[package.versioned_files]] path = "Cargo.toml" format = "toml"

[[package.versioned_files]] path = "npm/package.json" format = "json"

JSON5

{
  package: [
    {
      name: "my-app",
      path: ".",
      versionedFiles: [
        { path: "Cargo.toml", format: "toml" },
        { path: "npm/package.json", format: "json" },
      ],
    },
  ],
}

YAML

package:
  - name: my-app
    path: "."
    versionedFiles:
      - path: Cargo.toml
        format: toml
      - path: npm/package.json
        format: json
format File Field updated
toml Cargo.toml, pyproject.toml [package].version or [project].version
json package.json version
xml pom.xml First element
gradle build.gradle, build.gradle.kts version = "..."
gomod go.mod No file update — version comes from git tags only
txt VERSION, VERSION.txt Entire file content replaced

Complete examples

Single repo

JSON

{
  "$schema": "https://ferrflow.com/schema/ferrflow.json",
  "workspace": {
    "tagTemplate": "v{version}"
  },
  "package": [
    {
      "name": "ferrflow",
      "path": ".",
      "changelog": "CHANGELOG.md",
      "versionedFiles": [
        { "path": "Cargo.toml", "format": "toml" },
        { "path": "npm/package.json", "format": "json" }
      ]
    }
  ]
}

TOML

[workspace]
tag_template = "v{version}"

[[package]] name = "ferrflow" path = "." changelog = "CHANGELOG.md"

[[package.versioned_files]] path = "Cargo.toml" format = "toml"

[[package.versioned_files]] path = "npm/package.json" format = "json"

JSON5

{
  $schema: "https://ferrflow.com/schema/ferrflow.json",
  workspace: {
    tagTemplate: "v{version}",
  },
  package: [
    {
      name: "ferrflow",
      path: ".",
      changelog: "CHANGELOG.md",
      versionedFiles: [
        { path: "Cargo.toml", format: "toml" },
        { path: "npm/package.json", format: "json" },
      ],
    },
  ],
}

YAML

workspace:
  tagTemplate: "v{version}"

package:

  • name: ferrflow path: "." changelog: CHANGELOG.md versionedFiles:
    • path: Cargo.toml format: toml
    • path: npm/package.json format: json

Monorepo

JSON

{
  "$schema": "https://ferrflow.com/schema/ferrflow.json",
  "workspace": {
    "tagTemplate": "{name}@v{version}"
  },
  "package": [
    {
      "name": "api",
      "path": "packages/api",
      "changelog": "packages/api/CHANGELOG.md",
      "sharedPaths": ["packages/shared/"],
      "versionedFiles": [
        { "path": "packages/api/Cargo.toml", "format": "toml" }
      ]
    },
    {
      "name": "site",
      "path": "packages/site",
      "changelog": "packages/site/CHANGELOG.md",
      "sharedPaths": ["packages/shared/"],
      "versionedFiles": [
        { "path": "packages/site/package.json", "format": "json" }
      ]
    }
  ]
}

TOML

[workspace]
tag_template = "{name}@v{version}"

[[package]] name = "api" path = "packages/api" changelog = "packages/api/CHANGELOG.md" shared_paths = ["packages/shared/"]

[[package.versioned_files]] path = "packages/api/Cargo.toml" format = "toml"

[[package]] name = "site" path = "packages/site" changelog = "packages/site/CHANGELOG.md" shared_paths = ["packages/shared/"]

[[package.versioned_files]] path = "packages/site/package.json" format = "json"

JSON5

{
  $schema: "https://ferrflow.com/schema/ferrflow.json",
  workspace: {
    tagTemplate: "{name}@v{version}",
  },
  package: [
    {
      name: "api",
      path: "packages/api",
      changelog: "packages/api/CHANGELOG.md",
      sharedPaths: ["packages/shared/"],
      versionedFiles: [
        { path: "packages/api/Cargo.toml", format: "toml" },
      ],
    },
    {
      name: "site",
      path: "packages/site",
      changelog: "packages/site/CHANGELOG.md",
      sharedPaths: ["packages/shared/"],
      versionedFiles: [
        { path: "packages/site/package.json", format: "json" },
      ],
    },
  ],
}

YAML

workspace:
  tagTemplate: "{name}@v{version}"

package:

  • name: api path: packages/api changelog: packages/api/CHANGELOG.md sharedPaths:

    • packages/shared/ versionedFiles:
    • path: packages/api/Cargo.toml format: toml
  • name: site path: packages/site changelog: packages/site/CHANGELOG.md sharedPaths:

    • packages/shared/ versionedFiles:
    • path: packages/site/package.json format: json