Skip to content

Nx supports workspaces of any size and scale, and that means that projects can often be worked on in the same Nx workspace that have very different release requirements.

Nx release supports the concept of release groups to allow you to configure different subsets of projects in different ways. Importantly, projects in different release groups can still depend on each other, and nx release can automatically handle updating dependencies and dependents across any number of group boundaries.

Release groups provide a way to organize your projects based on their release requirements. Each group can have its own:

  • Projects Relationship - Whether projects within the group are versioned independently or in lock step (fixed)
  • Version configuration - Custom conventional commits, version prefixes, and more
  • Changelog configuration - Different changelog formats and locations
  • Release tag - Various options related to the git tags that influence the release process
  • Docker configuration - Specific Docker versioning schemes

To create release groups, define them in your nx.json file under the release.groups property:

nx.json
{
"release": {
"groups": {
"backend": {
"projects": ["api", "auth-service", "payment-service"],
"projectsRelationship": "fixed"
},
"frontend": {
"projects": ["web-app", "mobile-app"],
"projectsRelationship": "independent"
}
}
}
}

You can specify projects for a group using project matchers that you may already be familiar with from nx run-many command filters:

  • Explicit project names: "projects": ["project-a", "project-b"]
  • Glob patterns: "projects": ["packages/shared-*"]
  • Tag references: "projects": ["tag:npm-public"]
  • Negation: "projects": ["!ignore-me"]

The projectsRelationship property determines how projects within a group are released:

When projectsRelationship is set to "fixed" (the default):

  • All projects in the group share the same version number
  • When one project requires a version bump, all projects in the group are versioned together
  • Dependencies between projects in the group are always automatically updated
  • Each project will receive a changelog entry, with a specific (configurable) message for those projects that were only bumped to align with the group version
nx.json
{
"release": {
"groups": {
"shared-libraries": {
"projects": ["ui-components", "utils", "data-access"],
// this is also the default and can be omitted
"projectsRelationship": "fixed"
// ... other group configuration options ...
}
}
}
}

When projectsRelationship is set to "independent":

  • Each project in the group maintains its own version
  • Projects are versioned only when they have changes (apart from the influence of "updateDependents" configuration, learn more below)
  • Changelog entries are generated only when there are direct or indirect ("updateDependents") changes to the project
nx.json
{
"release": {
"groups": {
"microservices": {
"projects": ["user-service", "order-service", "inventory-service"],
"projectsRelationship": "independent"
// ... other group configuration options ...
}
}
}
}

Each release group can override the root "release" configuration with its own settings:

Customize versioning behavior per group:

{
"release": {
"version": {
"conventionalCommits": false,
"versionPrefix": "~",
"updateDependents": "always"
},
"groups": {
"npm-packages": {
"projects": ["package-*"],
"version": {
// These properties override the root version
//configuration for this specific group
"conventionalCommits": true,
"versionPrefix": "^",
"updateDependents": "auto"
}
}
}
}
}

Configure changelog generation per group:

{
"release": {
"changelog": {
"projectChangelogs": {
"file": false
// ... other changelog configuration options ...
}
},
"groups": {
"public-apis": {
"projects": ["api-*"],
// overrides at the group level
"changelog": {
"file": "{projectRoot}/CHANGELOG.md",
"createRelease": "github",
"renderer": "@my-org/custom-changelog-renderer"
}
}
}
}
}

Customize how relevant git tags should be discovered and created for each group independently:

{
"release": {
"groups": {
"backend": {
"projects": ["backend-*"],
"releaseTag": {
"pattern": "backend-{version}",
"requireSemver": true
}
},
"frontend": {
"projects": ["frontend-*"],
"releaseTag": {
"pattern": "frontend-{version}"
}
}
}
}
}

For independently versioned projects, regardless of whether they are in the same release group or not, we will have to consider what happens when those projects depend on one another.

nx.json
{
"release": {
"groups": {
"group1": {
// project-a depends on project-b, even though it
// happens to be in a different release group here
"projects": ["project-a"]
},
"group2": {
// project-a depends on project-b, even though it
// happens to be in a different release group here
"projects": ["project-b"]
}
}
}
}

Nx can handle this cascade of updates automatically, across any number of release group boundaries, and this behavior is configurable via the version.updateDependents option.

See the Update Dependents guide for more details.

You can have different relationship types for different groups in the same workspace:

{
"release": {
"groups": {
"platform": {
"projects": ["core", "common", "shared"],
"projectsRelationship": "fixed"
},
"applications": {
"projects": ["app-*"],
"projectsRelationship": "independent"
}
}
}
}

Run different build or preparation commands for each group:

{
"release": {
"groups": {
"compiled-packages": {
"projects": ["lib-*"],
"version": {
"groupPreVersionCommand": "nx run-many -t build --projects=..."
}
},
"documentation": {
"projects": ["docs-*"],
"version": {
"groupPreVersionCommand": "nx run-many -t generate-docs --projects=..."
}
}
}
}
}

When using version plans, you can target specific groups:

{
"release": {
"groups": {
"backend": {
"projects": ["api-*"],
"versionPlans": true
},
"frontend": {
"projects": ["ui-*"]
// version plans is not enabled here and
// it's not set at the root level either
}
}
}
}

Nx Release processes groups in topological order based on their dependencies:

  1. Groups with no dependencies are processed first
  2. Groups that depend on already-processed groups are processed next
  3. Within each group, projects are also processed in topological order

This ensures that:

  • Dependencies are always versioned before their dependents
  • Version updates cascade correctly through the ReleaseGraph that is constructed behind the scenes

NOTE: Circular dependencies are not recommended, but can be tolerated by nx release, as it can sometimes be unavoidable.

You can filter which groups or projects to release:

Terminal window
# Release only a specific group
nx release --groups=backend
# Release specific independent projects across any groups
nx release --projects=api,web-app
# Combine with dry-run to preview
nx release --groups=frontend --dry-run