{"id":26006913,"url":"https://github.com/vltpkg/reproduce","last_synced_at":"2025-10-10T19:36:10.601Z","repository":{"id":279664781,"uuid":"761578713","full_name":"vltpkg/reproduce","owner":"vltpkg","description":"Library to check if a package is reproducible","archived":false,"fork":false,"pushed_at":"2025-09-14T23:59:43.000Z","size":301,"stargazers_count":62,"open_issues_count":1,"forks_count":3,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-30T16:46:42.837Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/vltpkg.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-02-22T05:02:47.000Z","updated_at":"2025-09-14T23:59:46.000Z","dependencies_parsed_at":"2025-05-08T16:45:20.083Z","dependency_job_id":"36b5e1f0-01a2-4077-8cf3-c55f9181e8b5","html_url":"https://github.com/vltpkg/reproduce","commit_stats":null,"previous_names":["vltpkg/reproduce"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/vltpkg/reproduce","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vltpkg%2Freproduce","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vltpkg%2Freproduce/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vltpkg%2Freproduce/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vltpkg%2Freproduce/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vltpkg","download_url":"https://codeload.github.com/vltpkg/reproduce/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vltpkg%2Freproduce/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279005033,"owners_count":26083827,"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","status":"online","status_checked_at":"2025-10-10T02:00:06.843Z","response_time":62,"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":"2025-03-05T21:01:48.198Z","updated_at":"2025-10-10T19:36:10.595Z","avatar_url":"https://github.com/vltpkg.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"\u003cimg src=\"https://github.com/user-attachments/assets/e31faec6-a3b7-48d1-92a3-f88f0a5521f8\" alt=\"reproducible logo\" /\u003e\n\n# `reproduce`\n\n[![Test](https://github.com/vltpkg/reproduce/actions/workflows/test.yml/badge.svg)](https://github.com/vltpkg/reproduce/actions/workflows/test.yml)\n\nCan we reproduce a package with the _\"origin\"_ information provided?\n\n**[Features](#features)**\n·\n**[How It Works](#how-it-works)**\n·\n**[Configuration](#configuration)**\n·\n**[Strategies](#strategies)**\n·\n**[Usage](#usage)**\n·\n**[Insights](#insights)**\n·\n**[FAQs](#faqs)**\n\n### Features\n\n- ✅ determines whether or not a package can be reproduced from it's referenced repository metadata (ie. `repository`, `repository.type`, `repository.url`, `repository.directory` \u0026 `gitHead`)\n- 🔍 validates `repository` information against `package.json` if the package referenced lives on a registry (will fallback to `package.json` inside the tarball if the package is not in a registry)\n  - 🔀 mismatching `repository` information is considered [_\"manifest confusion\"_](https://blog.vlt.sh/blog/the-massive-hole-in-the-npm-ecosystem) \u0026 will return `false` for _\"reproducibility\"_\n- 🗄️ provides persistent caching of results\n- 🔄 currently only supports `npm` as a `\"strategy\"` but will expand to support other package managers in the future\n\n#### How It Works\n\n1. ⬇️ fetches the package \u0026 any corresponding metadata\n2. 📂 if available, does a clone/checkout of the corresponding source `repository`\n3. 🔄 attempts to prepare \u0026 pack the source repository using one or more [strategies](#strategies)\n4. 🔍 validates the integrity value of `#3` against the package fetched in `#1`\n5. 📄 returns results and caches them for future use\n\n### Usage\n\n```bash\n$ npm i -g reproduce # install globally\n$ reproduce axios\n```\n\n```bash\n$ npx reproduce axios # execute with npx\n```\n\n```js\nimport reproduce from 'reproduce'\n\n// Basic usage\nconst result = await reproduce('package-name')\n\n// With custom configuration\nconst result = await reproduce('package-name', {\n  cache: {},\n  cacheDir: './custom-cache',\n  cacheFile: 'custom-cache.json'\n})\n```\n\n\n#### CLI\n\n```bash\nreproduce tsc # exit code 0 - reproducible\n```\n\n```bash\nreproduce esbuild # exit code 1 - not reproducible\n```\n\n```bash\nreproduce axios --json  # exit code 1 - not reproducible\n{\n  \"reproduceVersion\": \"0.0.1-pre.1\",\n  \"timestamp\": \"2025-02-25T10:40:24.947Z\",\n  \"os\": \"darwin\",\n  \"arch\": \"arm64\",\n  \"strategy\": \"npm:10.9.1\",\n  \"reproduced\": false,\n  \"package\": {\n    \"spec\": \"axios@latest\",\n    \"name\": \"axios\",\n    \"version\": \"1.2.3\",\n    \"location\": \"https://registry.npmjs.org/axios/-/axios-1.7.9.tgz\",\n    \"integrity\": \"sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==\"\n  },\n  \"source\": {\n    \"spec\": \"github:axios/axios#b2cb45d5a533a5465c99559b16987e4d5fc08cbc\",\n    \"name\": \"axios\",\n    \"version\": \"1.2.3\",\n    \"location\": \"git+https://github.com/axios/axios.git\",\n    \"integrity\": \"null\"\n  },\n  \"diff\": \"...\"\n}\n```\n\n```bash\nreproduce axios --force  # force revalidation, bypass cache\n```\n\n##### CLI Options\n\n| Option | Short | Description |\n|--------|-------|-------------|\n| `--strategy` | `-s` | Choose a strategy (default: \"npm\") |\n| `--json` | `-j` | Output result as JSON |\n| `--force` | `-f` | Force revalidation, bypass cache |\n| `--help` | `-h` | Print usage information |\n\n```bash\nreproduce require --json  # exit code 0 - reproducible\n{\n  \"reproduceVersion\": \"0.0.1-pre.1\",\n  \"timestamp\": \"2025-02-25T10:22:09.303Z\",\n  \"os\": \"darwin\",\n  \"arch\": \"arm64\",\n  \"strategy\": \"npm:10.9.1\",\n  \"reproduced\": true,\n  \"package\": {\n    \"spec\": \"sleepover@latest\",\n    \"version\": \"1.2.3\",\n    \"location\": \"https://registry.npmjs.org/sleepover/-/sleepover-1.2.3.tgz\",\n    \"integrity\": \"sha512-yNAIVUqbQifyy5+hfzAzK2Zt21wXjwXqPyWLu+tOvhOcYKG2ffUiSoBXwt/yo4KJ51IcJfUS0Uq0ktOoMWy9Yw==\"\n  },\n  \"source\": {\n    \"spec\": \"github:darcyclarke/sleepover#f2586e91b3faf085583c23ed6e00819916e85c28\",\n    \"version\": \"1.2.3\",\n    \"location\": \"git+ssh://git@github.com/darcyclarke/sleepover.git\",\n    \"integrity\": \"sha512-yNAIVUqbQifyy5+hfzAzK2Zt21wXjwXqPyWLu+tOvhOcYKG2ffUiSoBXwt/yo4KJ51IcJfUS0Uq0ktOoMWy9Yw==\"\n  }\n}\n```\n\n### Configuration\n\nThe `reproduce` function accepts an options object with the following configuration:\n\n```js\n{\n  cache: {},                      // Optional in-memory cache object (persisted to disk if provided)\n  cacheDir: '~/.cache/reproduce', // OS-specific cache directory\n  cacheFile: 'cache.json',        // Cache file name\n  strategy: 'npm'                 // Strategy to use\n}\n```\n\n#### Cache Locations\n\nThe cache is stored in OS-specific locations:\n- macOS: `~/Library/Caches/reproduce/`\n- Windows: `%LOCALAPPDATA%/reproduce/Cache/`\n- Linux: `$XDG_CACHE_HOME/reproduce/` or `~/.cache/reproduce/`\n\n### Strategies\n\nA strategy is a set of operations to take to recreate a package. Strategies should represent common patterns for preparing/building/packing packages to cast wide nets. If a set successfully recreates a package then its ID will be stored inside the returned metadata.\n\n| Name | UUID |  Description |\n| --- | --- |\n| `npm` `npm:\u003cversion\u003e` | clones, checks out ref, installs deps \u0026 then runs pack |\n\n\u003e Note: one-off/bespoke or complex configurations will not be supported but we will continue to add more strategies as we find common patterns.\n\n### Insights\n\n#### Top 5,000 High Impact Packages\n\n\u003e Note: \"High Impact\" packages are defined as having \u003e=1M downloads per week and/or \u003e=500 dependants. This list was originally generated [here](http://github.com/nodejs/package-maintenance/issues/569#issuecomment-1739532894). This test was run on 2025-02-26.\n\n- **5.78%** (289) are **reproducible**\n- **3.72%** (186) have **provenance**\n\n\u003cdetails\u003e\n\u003csummary\u003eList of reproducible packages\u003c/summary\u003e\n\u003cpre\u003e\nsemver\ntslib\nlru-cache\nreadable-stream\nansi-regex\ncommander\nminimatch\nyallist\nglob\nstring-width\nfs-extra\nemoji-regex\nwhich\nexeca\nws\nminipass\ncross-spawn\nmicromatch\nwhatwg-url\ntr46\nmime\npath-type\nloader-utils\nwrite-file-atomic\ncallsites\nini\nbinary-extensions\nis-binary-path\npump\nread-pkg\nnormalize-package-data\nopen\njson-parse-even-better-errors\ncli-cursor\nyocto-queue\nrestore-cursor\nterser\nfastq\nsax\nip\nlog-symbols\nreusify\nssri\nnopt\nnormalize-url\n@eslint/eslintrc\n@humanwhocodes/config-array\nmdn-data\nmute-stream\nimport-local\ngauge\nspdx-license-ids\ntest-exclude\nregjsparser\nspdx-exceptions\nis-unicode-supported\nis-ci\nurl\nsource-map-js\nregenerate-unicode-properties\nminizlib\nunicode-match-property-value-ecmascript\ndata-urls\nhtml-encoding-sniffer\nwhatwg-mimetype\ncli-spinners\nxml-name-validator\nabbrev\ntype\nunicode-canonical-property-names-ecmascript\nunique-slug\nunique-filename\nw3c-xmlserializer\ndot-prop\ncamelcase-keys\n@sindresorhus/is\nforeground-child\n@npmcli/fs\nstream-shift\nlog-update\nmake-fetch-happen\nboxen\ndel\ntar-fs\n@hapi/hoek\np-retry\nhas-ansi\nminipass-fetch\ncli-boxes\nagentkeepalive\nsort-keys\nsafe-stable-stringify\nnode-gyp-build\nnpm-normalize-package-bin\nbuiltins\naws-sdk\nelliptic\nnpm-package-arg\nvalidate-npm-package-name\nes5-ext\nes6-symbol\nstrnum\npath-scurry\nregistry-auth-token\ncrypto-browserify\nd\nhtml-tags\nmoment-timezone\nnpm-bundled\nignore-walk\nnpm-packlist\ndevtools-protocol\nget-port\npackage-json\np-defer\np-event\nlatest-version\ndefault-browser-id\nnpm-registry-fetch\ncompress-commons\nzip-stream\nlcid\nfilter-obj\nnpm-pick-manifest\npacote\nread\nrequire-in-the-middle\nnpm-install-checks\nthrottleit\n@npmcli/run-script\ntouch\nread-package-json-fast\n@npmcli/promise-spawn\n@npmcli/node-gyp\n@npmcli/git\nprebuild-install\nstore2\n@npmcli/installed-package-contents\nproc-log\npostgres-interval\nxregexp\nwebpack-hot-middleware\nis-what\ncopy-anything\nset-cookie-parser\np-filter\nfast-redact\nknown-css-properties\nremark-slug\nis-builtin-module\nremark-external-links\nis-text-path\ntext-extensions\nmemoizee\ntimers-ext\nspawn-command\nfind-versions\ndebounce\nxmlhttprequest-ssl\npino-abstract-transport\nrun-applescript\nuse-callback-ref\nuse-sidecar\nestree-to-babel\ndefault-browser\nbundle-name\npretty-ms\npostcss-normalize\ncli-color\nmacos-release\nwindows-release\nremark-footnotes\nimport-in-the-middle\nread-cmd-shim\ncpy\nwrite-json-file\ncron-parser\nfind-babel-config\nlru-memoizer\nunzipper\nwinston-daily-rotate-file\nobliterator\ncsv-parser\nmnemonist\nset-immediate-shim\nthrough2-filter\ninit-package-json\nwinston-logzio\n@npmcli/package-json\npromzard\ns3-streamlogger\nbin-links\n@npmcli/map-workspaces\n@npmcli/name-from-folder\nwalk-up-path\nast-module-types\nunion\nwhy-is-node-running\n@npmcli/metavuln-calculator\nhot-shots\nparse-conflict-json\noidc-token-hash\nprom-client\nmarked-terminal\npromise-call-limit\nnode-source-walk\nlibmime\nlogzio-nodejs\npostcss-sorting\n@zeit/schemas\nethereum-cryptography\nparse-github-url\nlight-my-request\ndetective-stylus\nn\ncomment-json\ndetective-typescript\n@lezer/common\n@lezer/lr\nprecinct\nredux-mock-store\ndetective-postcss\ntwilio\nlog\ntocbot\n@hapi/podium\ndetective-es6\nget-amd-module-type\ndetective-sass\ndetective-scss\ndetective-cjs\ngenerate-object-property\nsprintf-kit\nhighcharts\ngraphql-subscriptions\n@tailwindcss/forms\njspdf\nchance\neslint-plugin-react-native\n\u003c/pre\u003e\n\u003c/details\u003e\n\n### FAQs\n\n#### Why look into \"reproducibility\"?\n\nWe believe the strategy of leveraging reproducible builds for the purpose of associating artifacts with a source/repository outperforms the current provenance strategy with the added benefit of being backwards compatible.\n\n#### Will reproducibility get better with time?\n\nYes. As we add more strategies, we should see the percentatge of reproducible packages grow over time both net-new \u0026 previously published packages will benefit from the additional strategies. Feel free to contribute!\n\n### Credits\n\nBig thanks to [@siddharthkp](https://github.com/siddharthkp) for gifting the package name `reproduce` to us!\n\n### Learn More\n\nWe wrote a blog post about this project \u0026 the results we found which you can read here: https://blog.vlt.sh/blog/reproducibility\n\n\u003ca href=\"https://blog.vlt.sh/blog/reproducibility\"\u003e\u003cimg src=\"https://github.com/user-attachments/assets/65cb6e3f-8673-49ba-9e5c-94e80925690f\" alt=\"Is your package reproducible?\" /\u003e\u003c/a\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvltpkg%2Freproduce","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvltpkg%2Freproduce","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvltpkg%2Freproduce/lists"}