{"id":15537341,"url":"https://github.com/nullvoxpopuli/defrag","last_synced_at":"2025-04-23T13:45:11.251Z","repository":{"id":219357686,"uuid":"748867800","full_name":"NullVoxPopuli/defrag","owner":"NullVoxPopuli","description":"tool to defragment your monorepo (reduce divergent dependencies). get faster installs. prevent dependency disagreements in eslint, prettier, and typescript","archived":false,"fork":false,"pushed_at":"2024-01-28T18:44:17.000Z","size":195,"stargazers_count":12,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-15T11:39:52.469Z","etag":null,"topics":["clean","cleanup","defrag","defragmentation","dependencies","divergence","divergent","management","npm","optimization","pnpm","yarn"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/NullVoxPopuli.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-01-26T22:59:44.000Z","updated_at":"2024-12-06T18:32:26.000Z","dependencies_parsed_at":"2024-01-26T23:15:25.804Z","dependency_job_id":"22fc2509-f7db-49c1-9c26-7cf9d056d96a","html_url":"https://github.com/NullVoxPopuli/defrag","commit_stats":null,"previous_names":["nullvoxpopuli/defrag"],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NullVoxPopuli%2Fdefrag","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NullVoxPopuli%2Fdefrag/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NullVoxPopuli%2Fdefrag/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NullVoxPopuli%2Fdefrag/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NullVoxPopuli","download_url":"https://codeload.github.com/NullVoxPopuli/defrag/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250442039,"owners_count":21431252,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["clean","cleanup","defrag","defragmentation","dependencies","divergence","divergent","management","npm","optimization","pnpm","yarn"],"created_at":"2024-10-02T11:56:16.223Z","updated_at":"2025-04-23T13:45:11.236Z","avatar_url":"https://github.com/NullVoxPopuli.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Defrag\n\nDe-fragment the dependencies your monorepo, reducing the number of copies of in-range dependencies \n\nThis will sync all the versions in your monorepo to the same version, _within_ the configured range.\n\n**Works with all package-managers (pnpm, yarn, npm, etc)**\n\n## Usage\n\nRun in the root of your monorepo\n\n```bash\nnpx defrag\n```\n\nor debug with\n\n```bash\nDEBUG=defrag npx defrag\n```\n\n## Erroring in C.I.\n\nIn GitHub Actions\n\n```yaml\nensure-no-divergence:\n  runs-on: ubuntu-latest\n  steps:\n    - uses: actions/checkout@v4\n    - run: npx defrag\n    - run: git diff --exit-code\n```\n\nNo need to install dependencies for your monorepo to have this verification\n\n## Config\n\nExample `.defragrc.yaml`\n\n```yaml\n# When writing to package.json,\n# remove the semver-range, pinning the dependencie\n# to an exact version.\n#\n# Possible values:\n#  pinned ( default )\n#  patches ( e.g.:  ~1.0.0 )\n#  minors ( e.g.: ^1.0.0 )\nwrite-as: pinned \n\n# This whole object is optional, \n# but if your monorepo has public libraries\n# where you *need* wider ranges, that can be configured here\n# \n# overrides is an array of objects\noverrides:\n  # path may be either a single glob or an array of glabs\n  - path: \n    - packages/*/addon/package.json\n    - packages/*/*/package.json\n    # for both devDependencies and dependencies\n    # in addition to the 3 global options, \n    # pinned, patches, and minors, you may also\n    # specify `false` to disable version re-writing entirely\n    # (which may be useful for some packages that do \n    #  complex multi-version specifiers)\n    devDependencies: pinned\n    dependencies: minors \n\n# Default assumes every package follows semver (minors) and\n# is 100% safe to upgrade within those ranges.\n#\n# in practice, this is only true if all dependencies\n# sharing those listed here do not use private APIs.\n#\n# Due to private API usage (or relying on \"undefined\" behavior)\n# we are more conservative with these ranges and will deal with\n# them more manually.\nupdate-range:\n  \"~\":\n    - ember-source\n    - ember-data\n    - \"@ember-data/*\"\n```\n\n## Questions\n\n### Disable for sub-folders?\n\n```yaml\noverrides:\n  - path: packages/**/*\n    devDependencies: false\n    dependencies: false \n```\n\n### What does this do?\n\nThe algorithm is this:\n```\nscan all workspaces' package.json,\n  find the dependencies, adding their versions to a list\nfor each workspace\n  for each dependency\n    re-assign an in-range version to the highest the monorepo was already using\n```\n- reduces lockfile size\n- reduces duplicate depenedncies\n- allows package managers that \"hoist\" dependencies to be likely more correct\n\n### How is this different from dedupe?\n\nDedupe operates on the lockfile, only and `defrag` gives you more control over _what_ dedupes, based on ranges in a configured `.defragrc.yaml`.\nadditionally, this tool gives the ability to `pin` versions, whereas dedupe would use whatever resolved dependency version satisfies the pre-existing `^` range.\n\n### Can this break my lockfile? \n\nIf a package.json using a version format that isn't actually a version (and not yet accounted for), this is likely a bug -- the desired behavior is to ignore invalid versions and opt them out of being changed by this tool.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnullvoxpopuli%2Fdefrag","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnullvoxpopuli%2Fdefrag","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnullvoxpopuli%2Fdefrag/lists"}