This brief guide will demonstrate how to configure an NX monorepo to cancel unaffected builds in Netlify.

1) The stop-build plugin
This plugin will be used by all apps in the monorepo to determine whether it has been affected and cancel the build in Netlify.
- Create a new directory in the root of your NX project:
/tools/plugins/stop-build/ - Create an index.js file in this directory and add the following code:
module.exports = { onBuild: ({ utils }) => { const currentProject = process.env.PROJECT_NAME; const lastDeployedCommit = process.env.CACHED_COMMIT_REF; const latestCommit = 'HEAD'; const projectHasChanged = projectChanged( currentProject, lastDeployedCommit, latestCommit, ); if (!projectHasChanged) { utils.build.cancelBuild( `Build was cancelled because ${currentProject} was not affected by the latest changes`, ); } }, }; function projectChanged(currentProject, fromHash, toHash) { const execSync = require('child_process').execSync; const getAffected = `npx nx show projects --affected --base=${fromHash} --head=${toHash}`; const changedProjects = execSync(getAffected).toString(); return changedProjects.includes(currentProject); }
- Create a manifest.yml file, and add the following:
name: netlify-skip-build
2) The netlify.toml
- In each app in the monorepo, add a netlify.toml file (or update an existing), and add the following, with the path to the plugin added in the previous step:
[[plugins]] package = "/netlify/tools/plugins/stop-build"
3) Environment Variables
- For each app in Netlify, add an environment variable PROJECT_NAME with the app name as it is in the monorepo:

4) More control
I have a mixture of deployment contexts:
- Deploy previews
- ‘develop’ branch deploy
- Manual deploy (via CI) to ‘test’ alias
- Manual deploy (via CI) to ‘staging’ alias
- Production deploy
The 2 manual deploys allows the developers to select the specific app they want to deploy, and the environment (via alias, test or staging). In these 2 cases we don’t determine affected apps, so don’t need to run the plugin.
To restrict when the plugin runs, update the netlify.toml in each app to specify when the plugin is used:
[[context.production.plugins]] package = "/netlify/tools/plugins/stop-build" [[context.deploy-preview.plugins]] package = "/netlify/tools/plugins/stop-build" [[context.develop.plugins]] package = "/netlify/tools/plugins/stop-build"
The update above results in the plugin only being used when:
- Production deploys run
- Deploy previews are created (triggered from PRs)
- The ‘develop’ branch deploy is triggered
Done!