Skip to content

License

Manage licensing across your workspace: synchronise LICENSE files and source code headers for your own code (license.source), and check that every dependency conforms to a license allowlist (license.dependencies).

  1. Install the Nx Console VSCode Plugin if you haven't already
  2. Open the Nx Console in VSCode
  3. Click Generate (UI) in the "Common Nx Commands" section
  4. Search for @aws/nx-plugin - license
  5. Fill in the required parameters
    • Click Generate
    Parameter Type Default Description
    license Apache-2.0 | MIT | ASL Apache-2.0 SPDX License Identifier for your chosen license
    copyrightHolder string Amazon.com, Inc. or its affiliates The copyright holder, included in the LICENSE file and source file headers by default.
    dependencyCheck boolean true Configure a license-check target that fails when dependencies declare licenses outside the configured allowlist.
    preferInstallDependencies boolean true Whether to prefer installing dependencies after the generator runs. Set to false to defer installing when batching multiple generators (an install still runs if needed so subsequent generators can compute the Nx project graph); install once at the end.

    The generator will create or update the following files:

    • nx.json The lint target is configured to run the license sync generator and depends on the license-check target
    • aws-nx-plugin.config.mts Configuration for license source sync (license.source) and dependency checking (license.dependencies)

    The generator registers a sync generator to execute as part of your lint targets which ensures that your source files contain the correct license headers, your projects contain LICENSE files, and licensing metadata is set in package.json and pyproject.toml.

    Whenever you build your projects (and a lint target runs), the license sync generator will make sure that the licensing in your project matches your configuration. If it detects that anything is out of sync, you will receive a message such as:

    Terminal window
    NX The workspace is out of sync
    [@aws/nx-plugin:license#sync]: Project LICENSE files are out of sync:
    - LICENSE
    - packages/<my-project>LICENSE
    Project package.json files are out of sync:
    - package.json
    Project pyproject.toml files are out of sync:
    - pyproject.toml
    - packages/<my-python-project>/pyproject.toml
    License headers are out of sync in the following source files:
    - packages/<my-project>/src/index.ts
    - packages/<my-python-project>/main.py
    This will result in an error in CI.
    ? Would you like to sync the identified changes to get your workspace up to date?
    Yes, sync the changes and run the tasks
    No, run the tasks without syncing the changes

    Select Yes to sync the changes.

    The license sync generator performs three main tasks:

    1. Synchronise Source File License Headers

    Section titled “1. Synchronise Source File License Headers”

    When the sync generator is run, it will ensure that all source code files in your workspace (based on your configuration) contain the appropriate license header. The header is written as the first block comment or consecutive series of line comments in the file (besides the shebang/hashbang if present in a file).

    When the sync generator is run, it will ensure that the root LICENSE file corresponds to your configured license, as well as ensuring that all subprojects in your workspace also contain the correct LICENSE file.

    3. Synchronise licensing information in project files

    Section titled “3. Synchronise licensing information in project files”

    When the sync generator is run, it will ensure the license fields in package.json and pyproject.toml files are set to your configured license.

    Configuration is defined in the aws-nx-plugin.config.mts file in the root of your workspace.

    Your chosen license can be updated at any time via the spdx configuration property:

    aws-nx-plugin.config.mts
    export default {
    license: {
    source: {
    spdx: 'MIT',
    },
    },
    } satisfies AwsNxPluginConfig;

    When the sync generator runs, all LICENSE files, package.json and pyproject.toml files will be updated to reflect the configured license.

    You can additionally configure the copyright holder and copyright year, which are included in some LICENSE files:

    aws-nx-plugin.config.mts
    export default {
    license: {
    source: {
    spdx: 'MIT',
    copyrightHolder: 'Amazon.com, Inc. or its affiliates',
    copyrightYear: 2025,
    },
    },
    } satisfies AwsNxPluginConfig;

    The license header content can be configured in two ways:

    1. Using inline content:
    aws-nx-plugin.config.mts
    export default {
    license: {
    source: {
    header: {
    content: {
    lines: [
    'Copyright: My Company, Incorporated.',
    'Licensed under the MIT License',
    'All rights reserved',
    ];
    }
    // ... format configuration
    }
    }
    }
    } satisfies AwsNxPluginConfig;
    1. Loading from a file:
    aws-nx-plugin.config.mts
    export default {
    license: {
    source: {
    header: {
    content: {
    filePath: 'license-header.txt'; // relative to workspace root
    }
    // ... format configuration
    }
    }
    }
    } satisfies AwsNxPluginConfig;

    You can specify how license headers should be formatted for different file types using glob patterns. The format configuration supports line comments, block comments, or a combination of both:

    aws-nx-plugin.config.mts
    export default {
    license: {
    source: {
    header: {
    content: {
    lines: ['Copyright notice here'],
    },
    format: {
    // Line comments
    '**/*.ts': {
    lineStart: '// ',
    },
    // Block comments
    '**/*.css': {
    blockStart: '/*',
    blockEnd: '*/',
    },
    // Block comments with line prefixes
    '**/*.java': {
    blockStart: '/*',
    lineStart: ' * ',
    blockEnd: ' */',
    },
    // Line comments with header/footer
    '**/*.py': {
    blockStart: '# ------------',
    lineStart: '# ',
    blockEnd: '# ------------',
    },
    },
    },
    },
    },
    } satisfies AwsNxPluginConfig;

    The format configuration supports:

    • blockStart: Text written before the license content (e.g. to start a block comment)
    • lineStart: Text prepended to each line of the license content
    • lineEnd: Text appended to each line of the license content
    • blockEnd: Text written after the license content (e.g. to end a block comment)

    For file types that aren’t natively supported, you can specify custom comment syntax to tell the sync generator how to identify existing license headers in these file types.

    aws-nx-plugin.config.mts
    export default {
    license: {
    source: {
    header: {
    content: {
    lines: ['My license header'],
    },
    format: {
    '**/*.xyz': {
    lineStart: '## ',
    },
    },
    commentSyntax: {
    xyz: {
    line: '##', // Define line comment syntax
    },
    abc: {
    block: {
    // Define block comment syntax
    start: '<!--',
    end: '-->',
    },
    },
    },
    },
    },
    },
    } satisfies AwsNxPluginConfig;

    By default, in a git repository, all .gitignore files are honored to ensure that only files managed by version control are synchronized. In non-git repositories, all files are considered unless explicitly excluded in configuration.

    You can exclude additional files from license header synchronization using glob patterns:

    aws-nx-plugin.config.mts
    export default {
    license: {
    source: {
    header: {
    content: {
    lines: ['My license header'],
    },
    format: {
    '**/*.ts': {
    lineStart: '// ',
    },
    },
    exclude: ['**/generated/**', '**/dist/**', 'some-specific-file.ts'],
    },
    },
    },
    } satisfies AwsNxPluginConfig;

    All LICENSE files, package.json files and pyproject.toml files are synchronised with the configured license by default.

    You can exclude specific projects or files from synchronization using glob patterns:

    aws-nx-plugin.config.mts
    export default {
    license: {
    source: {
    files: {
    exclude: [
    // do not sync LICENSE file, package.json or pyproject.toml
    'packages/excluded-project',
    // do not sync LICENSE file, but sync package.json and/or pyproject.toml
    'apps/internal/LICENSE',
    ];
    }
    }
    }
    } satisfies AwsNxPluginConfig;

    License source sync is enabled by the presence of the license.source key in your configuration. To disable it:

    1. Remove the license.source section from your configuration in aws-nx-plugin.config.mts (you can keep license.dependencies if you still want dependency license checking)
    2. If you also want to fully remove the sync generator, remove the @aws/nx-plugin:license#sync generator from targetDefaults.lint.syncGenerators

    To re-enable license sync, simply run the license generator again.

    The license generator also configures a license-check target that fails when one of your project’s dependencies (or any transitive dependency) declares a license that is not in your allowlist.

    The generator writes a license-check target to your root project.json:

    project.json
    {
    "targets": {
    "license-check": {
    "executor": "@aws/nx-plugin:license-check",
    "cache": true,
    "inputs": [
    "{workspaceRoot}/pnpm-lock.yaml",
    "{workspaceRoot}/aws-nx-plugin.config.mts"
    ],
    "options": {}
    }
    }
    }

    The inputs are computed for your workspace: only lockfiles that are actually present are included, along with aws-nx-plugin.config.mts, plus a {workspaceRoot}/**/uv.lock glob when Python dependency checking is enabled (i.e. a Python collector is configured).

    You can run the check directly:

    Terminal window
    pnpm nx license-check

    Results are cached against your lockfiles and aws-nx-plugin.config.mts — re-runs are instant when nothing has changed.

    Collectors determine what gets scanned. The npmCollector uses license-checker-rseidelsohn, and the pythonCollector uses pip-licenses. If no installed dependencies are found, the check passes with nothing to inspect.

    The dependency license check runs automatically whenever you lint or build any project in your workspace. The license generator wires each project’s lint target to depend on the root license-check target, and the project generators (ts#* and py#*) do the same when they run — so the check is wired up regardless of the order generators are run in.

    This means you don’t need to run the check explicitly, though you can still do so with the license-check target:

    Terminal window
    pnpm nx license-check

    The wiring is a cross-project dependsOn on each project’s lint target that points at the root license-check target. To skip the check during a lint or build, set the LICENSE_DEPENDENCY_CHECK=skip environment variable:

    Terminal window
    pnpm LICENSE_DEPENDENCY_CHECK=skip lint

    By default the check uses a built-in set of common permissive licenses (MIT, Apache-2.0, BSD, ISC, etc.) exported as DEFAULT_LICENSE_ALLOWLIST. You can extend or override this in your config:

    aws-nx-plugin.config.mts
    import { AwsNxPluginConfig } from '@aws/nx-plugin';
    import { DEFAULT_LICENSE_ALLOWLIST } from '@aws/nx-plugin/sdk/license';
    export default {
    license: {
    // ...
    dependencies: {
    allow: [...DEFAULT_LICENSE_ALLOWLIST, { spdxId: 'LGPL-2.1-or-later', fullName: 'GNU Lesser General Public License v2.1 or later', aliases: [] }],
    exceptions: [
    { package: 'some-package', reason: 'Audited manually — ships MIT text without SPDX field' },
    ],
    },
    },
    } satisfies AwsNxPluginConfig;
    View the full list of licenses in DEFAULT_LICENSE_ALLOWLIST

    To restrict the allowlist, replace DEFAULT_LICENSE_ALLOWLIST with your own array. To extend it, spread the default and add entries. Entries are matched by SPDX id, full license name, or any of the listed aliases (case-insensitive).

    Use exceptions for packages that fail the check — either because their license is not in the allowlist, or because they ship without detectable license metadata. The reason field is required so reviewers can see why the exception was granted.

    exceptions: [
    {
    package: 'union',
    version: '0.5.0',
    reason: 'Package ships verbatim MIT text without declaring license',
    },
    ];

    Generators that introduce dependencies with problematic metadata (e.g. the MCP server generator) automatically add the required exceptions to your config when they run.

    Collectors discover dependencies and extract license metadata. The built-in collectors are npmCollector() (scans node_modules) and pythonCollector() (scans Python virtual environments). The license generator configures npmCollector() by default and adds pythonCollector() when Python projects are present.

    To implement a custom collector, conform to the LicenseCollector interface:

    import type { LicenseCollector } from '@aws/nx-plugin/sdk/license';
    const myCollector = (): LicenseCollector => ({
    name: 'my-ecosystem',
    traceCommand: 'my-tool why <package>',
    async collect({ workspaceRoot }) {
    return [
    { name: 'some-dep', version: '1.0.0', rawLicense: 'MIT', ecosystem: 'my-ecosystem' },
    ];
    },
    });

    license.dependencies accepts an optional onDependency callback that is invoked once for every discovered dependency, regardless of whether it passes or fails the check. It receives { package, spdx }, where package is the package name and spdx is the resolved SPDX license expression. An exception’s spdx takes precedence over the raw declared license, and spdx may be an empty string if no license was declared.

    This is a handy way to print out all of the licenses across your project. Run the license-check target to see the output:

    aws-nx-plugin.config.mts
    import { AwsNxPluginConfig } from '@aws/nx-plugin';
    import { DEFAULT_LICENSE_ALLOWLIST } from '@aws/nx-plugin/sdk/license';
    export default {
    license: {
    dependencies: {
    allow: DEFAULT_LICENSE_ALLOWLIST,
    onDependency: ({ package: pkg, spdx }) => {
    console.log(`${pkg} - ${spdx}`);
    },
    },
    },
    } satisfies AwsNxPluginConfig;

    Dependency license checking is enabled by the presence of the license.dependencies key in your configuration.

    To disable the checks for a single run, set the LICENSE_DEPENDENCY_CHECK=skip environment variable:

    Terminal window
    pnpm LICENSE_DEPENDENCY_CHECK=skip lint

    To disable permanently, remove the license.dependencies key from your configuration in aws-nx-plugin.config.mts. You can also re-run the license generator with --dependencyCheck=false to scaffold without it.