{"id":20731687,"url":"https://github.com/bgotink/package-constraints","last_synced_at":"2026-04-27T04:32:13.724Z","repository":{"id":42211938,"uuid":"176167331","full_name":"bgotink/package-constraints","owner":"bgotink","description":"Enforce constraints for dependencies in a package or workspace","archived":false,"fork":false,"pushed_at":"2023-01-06T01:43:33.000Z","size":108,"stargazers_count":0,"open_issues_count":4,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-02-01T14:16:12.899Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bgotink.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-03-17T22:15:45.000Z","updated_at":"2020-05-02T16:18:05.000Z","dependencies_parsed_at":"2023-02-05T02:00:21.941Z","dependency_job_id":null,"html_url":"https://github.com/bgotink/package-constraints","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/bgotink/package-constraints","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bgotink%2Fpackage-constraints","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bgotink%2Fpackage-constraints/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bgotink%2Fpackage-constraints/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bgotink%2Fpackage-constraints/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bgotink","download_url":"https://codeload.github.com/bgotink/package-constraints/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bgotink%2Fpackage-constraints/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32323213,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-26T23:26:28.701Z","status":"online","status_checked_at":"2026-04-27T02:00:06.769Z","response_time":128,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-17T05:16:24.831Z","updated_at":"2026-04-27T04:32:13.709Z","avatar_url":"https://github.com/bgotink.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# package-constraints\n\n\u003e Enforce rules for dependencies in a package or workspace\n\nConstraints provide the answer to many problems that arise when managing a workspace with a\nmultitude of packages:\n\n- How do I ensure all packages use consistent versions of a certain dependency?\n- How can I prevent packages A, B and C from depending on dependency X?\n- How can I force packages to put dependency Y in peerDependencies and never in dependencies?\n\nConstraints are written in prolog in a `constraints.pl` or `constraints.pro` file.\n\n## Warning\n\n__Warning__: this package is not stable, the CLI API and rules API is subject to change.\n\n## Inspiration\n\nThis package is heavily inspired on the current constraints implementation in `berry`, aka \"yarn v2\".\nIt is not compatible with `berry`, but that is subject to change.\n\n## Installation\n\n```bash\nyarn add -D package-constraints\n# or\nnpm install -D package-constraints\n```\n\n## Usage\n\nWe'll assume you use yarn throughout this usage guide. Replace `yarn` with `npx` if you're using\nnpm.\n\n```bash\nyarn constraints check\n```\n\nThis command will validate the constraints and log errors and a final result to stderr. If errors\nare found, the process will exit with a non-zero exit code.\n\nThe following options are available:\n\n- `--quiet`: don't log errors and final result to stderr\n- `--without-exit-code`: always exit with code `0` unless an unexpected error occurs, i.e. this will\n  make the command exit \"successfully\" if constraints are violated but it will exit with a non-zero\n  exit code if the constraints file is missing.\n- `--format`: Change the output format, the only supported value is [`tap`](https://testanything.org/).\n  If a format is passed, the output of `constraints` will be sent to stdout instead of stderr.\n- `--output-file FILE...`: Log output to file(s). Pass the option more than once to output to\n  multiple files. This option will add an initial output to the process, i.e. setting an output file\n  will not change whether the process logs the result via stdout/stderr. The `FILE` parameter may be\n  prefixed with a format, separated from the file path with a colon `:`.\n\nExample usage:\n\n```bash\nyarn constraints check --without-exit-code --output-file tap:/dev/fd/1 \\\n      | yarn tap-junit -n constraints.xml\n```\n\nTo help with debugging your constraints, you can generate the full constraints file using\n\n```bash\n# to output via stdio, e.g. to pipe to another process\nyarn constraints generate\n# or to store in a file\nyarn constraints generate full-constraints.pl\n```\n\nYou can then inspect the resulting prolog, or load it into a prolog engine to run some queries, e.g.\n\n```bash\nyarn constraints generate full-constraints.pl\nswipl -f full-constraints.pl\n```\n\n## Rules\n\nThe following rules are available, filled with the data from the `package.json` files in your\nworkspace:\n\n### `package/1`\n\n```prolog\npackage(PackageName).\n```\n\nThis rule matches all packages in your workspace.\n\n### `private_package/1`\n\n```prolog\nprivate_package(PackageName).\n```\n\nThis rule matches all private packages in your workspace.\n\n### `root_package/1`\n\n```prolog\nroot_package(PackageName).\n```\n\nThis rule matches the package name of the workspace root. If the workspace root doesn't have a name,\nas is possible for yarn workspaces, a dummy name will be used instead.\n\n### `dependency_type/1`\n\n```prolog\ndependency_type(peerDependencies).\ndependency_type(dependencies).\ndependency_type(devDependencies).\n```\n\nThis rule can be used to generate all dependency types. There are only three values: `dependencies`,\n`peerDependencies` and `devDependencies`.\n\n### `package_location/2`\n\n```prolog\npackage_location(PackageName, PackageLocation).\n```\n\nThis rule gives access to the location of a package, allowing rules to be written based on the\nfolder structure rather than the package name.\n\n### `package_version/2`\n\n```prolog\npackage_version(PackageName, Version).\n```\n\nThis rule links a workspace package with its version.\n\n### `package_has_dependency/4`\n\n```prolog\npackage_has_dependency(PackageName, DependencyName, DependencyVersion, DependencyType).\n```\n\nThis rule matches a package with its declared dependencies.\n\n## Queries\n\nThe constraints engine will look for matches for the following two predicates:\n\n### `gen_enforced_dependency_range/4`\n\n```prolog\ngen_enforced_dependency_range(PackageName, DependencyName, DependencyVersion, DependencyType).\n```\n\nThis rule is queried for every workspace package and every dependency type. The generated matches\nare compared with the actual dependencies listed in the workspace. If a difference is found, a\nviolation will be logged.\n\nUse a `DependencyVersion` value of `null` to mark a dependency as not allowed.\n\n### `gen_invalid_dependency/4`\n\n```prolog\ngen_invalid_dependency(PackageName, DependencyName, DependencyType, Reason).\n```\n\nThis rule is queried for every workspace package and every dependency type. Every generated match\nwill be logged as violation.\n\n## Recipes for constraints\n\nThis section contains a couple of recipes for constraints.\n\n### Force packages to depend on the workspace version of workspace packages\n\nThe following rule requires all dependencies on packages contained in the workspace itself to use\nthe version in the workspace:\n\n```prolog\ngen_enforced_dependency_range(PackageName, DependencyName, DependencyVersion, DependencyType) :-\n  package_has_dependency(PackageName, DependencyName, _, DependencyType),\n  package_version(DependencyName, DependencyVersion).\n```\n\n### Require all peerDependencies to be listed in devDependencies\n\nPeer-dependencies aren't installed automatically, so for local development these need to be\ninstalled separately. The following rule enforces all peer dependencies to be listed as dev\ndependency, ensuring the package is installed by your package manager.\n\n```prolog\ngen_enforced_dependency_range(PackageName, DependencyName, DependencyVersion, devDependencies) :-\n  package_has_dependency(PackageName, DependencyName, DependencyVersion, peerDependencies),\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbgotink%2Fpackage-constraints","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbgotink%2Fpackage-constraints","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbgotink%2Fpackage-constraints/lists"}