{"id":13483413,"url":"https://github.com/JamieMason/shrinkpack","last_synced_at":"2025-03-27T14:31:17.707Z","repository":{"id":27295683,"uuid":"30769486","full_name":"JamieMason/shrinkpack","owner":"JamieMason","description":"Fast, resilient, reproducible builds with npm install.","archived":false,"fork":false,"pushed_at":"2023-02-16T23:23:21.000Z","size":4329,"stargazers_count":793,"open_issues_count":3,"forks_count":38,"subscribers_count":14,"default_branch":"master","last_synced_at":"2024-10-29T17:12:37.281Z","etag":null,"topics":["ci","cli","dependencies","dependency","dependency-manager","install","lockfile","npm","offline-mirror","package","package-json","package-lock","pnpm","shrinkwrap","yarn"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/shrinkpack","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/JamieMason.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null},"funding":{"github":"JamieMason"}},"created_at":"2015-02-13T18:20:14.000Z","updated_at":"2024-09-29T10:56:15.000Z","dependencies_parsed_at":"2024-01-02T23:42:17.785Z","dependency_job_id":"a77b9be7-7a65-467a-93cb-fec8fa418887","html_url":"https://github.com/JamieMason/shrinkpack","commit_stats":{"total_commits":150,"total_committers":12,"mean_commits":12.5,"dds":0.1266666666666667,"last_synced_commit":"ba19806467afe58a4507567898ea38d73aab9b41"},"previous_names":[],"tags_count":28,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JamieMason%2Fshrinkpack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JamieMason%2Fshrinkpack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JamieMason%2Fshrinkpack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JamieMason%2Fshrinkpack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JamieMason","download_url":"https://codeload.github.com/JamieMason/shrinkpack/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245863076,"owners_count":20684784,"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":["ci","cli","dependencies","dependency","dependency-manager","install","lockfile","npm","offline-mirror","package","package-json","package-lock","pnpm","shrinkwrap","yarn"],"created_at":"2024-07-31T17:01:10.970Z","updated_at":"2025-03-27T14:31:17.681Z","avatar_url":"https://github.com/JamieMason.png","language":"TypeScript","readme":"# shrinkpack\n\n\u003e Fast, resilient, reproducible builds with npm install.\n\n[![NPM version](http://img.shields.io/npm/v/shrinkpack.svg?style=flat-square)](https://www.npmjs.com/package/shrinkpack)\n[![NPM downloads](http://img.shields.io/npm/dm/shrinkpack.svg?style=flat-square)](https://www.npmjs.com/package/shrinkpack)\n[![Follow JamieMason on GitHub](https://img.shields.io/github/followers/JamieMason.svg?style=social\u0026label=Follow)](https://github.com/JamieMason)\n[![Follow fold_left on Twitter](https://img.shields.io/twitter/follow/fold_left.svg?style=social\u0026label=Follow)](https://twitter.com/fold_left)\n\n## What\n\n`shrinkpack` points your `package-lock.json` at [npm](https://www.npmjs.com/)\ntarballs checked into your project's source control, so you can install while\noffline, during a registry outage, or during the next\n[left-pad incident](https://blog.npmjs.org/post/141577284765/kik-left-pad-and-npm.html).\n\n## How\n\n1. Read `package-lock.json` or `npm-shrinkwrap.json`.\n1. Download the exact same .tgz files that `npm install` fetches from\n   [registry.npmjs.org](https://registry.npmjs.org).\n1. Decompress the .tgz files into .tar files. This avoids storing binary files\n   in Git and removes the cost of decompression during `npm install`.\n1. Store the .tar files in your project at `node_shrinkpack/*.tar`.\n1. Rewrite `package-lock.json` to point at those instead of the registry.\n\nNow your project can be installed while completely offline:\n\n```diff\n- npm install\n+ npm ci --offline\n```\n\nThe rest of the npm installation process is exactly the same. The only\ndifference is that no network activity is necessary when installing and building\nyour project. The `node_shrinkpack` directory can be ignored in your editor\n(much like is done with the `node_modules` directory), but is instead checked\ninto source control.\n\n## Why\n\nFor context, please see the [target problem](#target-problem) and\n[justification](#justification) sections of this README.\n\n## Installation\n\n\u003e Requires npm@7 or higher.\n\n```\nnpm install --global shrinkpack\n```\n\n## Usage\n\nRun `shrinkpack` every time you have modified and installed your dependencies to\nproduce a new `package-lock.json`.\n\n```\nUsage: shrinkpack [options] [directory]\n\nOptions:\n  -V, --version  output the version number\n  -h, --help     display help for command\n\nIcons:\n  + Added\n  - Removed\n  i Information\n  12:34 Time Taken\n```\n\n## History\n\n1. **Feb 2015**: shrinkpack was created.\n1. **Mar 2016**: The\n   [left-pad incident](https://blog.npmjs.org/post/141577284765/kik-left-pad-and-npm.html)\n   happened (shrinkpack users were unaffected!).\n1. **Jun 2016**:\n   [yarn added \"offline mirror\" support](https://github.com/yarnpkg/yarn/commit/1e7a1818b3ebf7825a2213770eb340e60ce30288).\n1. **May 2017**:\n   [npm@5 added package-lock.json](https://github.com/npm/npm/commit/ba50bdb0f0bbbae234eb4d8d87c261c29b506f8b)\n   but\n   [npm@5 broke support for installing local files from a lockfile](https://github.com/JamieMason/shrinkpack/issues/83).\n   Subsequent fixes were released for npm, but the issue was not resolved.\n1. **Apr 2018**: npm announced plans to\n   [integrate shrinkpack functionality into npm](https://blog.npmjs.org/post/173239798780/beyond-npm6-the-future-of-the-npm-cli.html).\n1. **May 2018**: Work on shrinkpack is abandoned after\n   [the regression in npm@5 is still not fixed after a year](https://github.com/JamieMason/shrinkpack/issues/83#issuecomment-386340937).\n1. **Dec 2021**: [Jack Franklin](https://twitter.com/Jack_Franklin) wrote\n   [why you should check-in your node dependencies](https://www.jackfranklin.co.uk/blog/check-in-your-node-dependencies/)\n   and I'm reminded of\n   [why I wrote shrinkpack in the first place](#target-problem).\n1. **Dec 2021**: Work resumes on shrinkpack and support is added for npm \u003e= 7.\n\n## Target Problem\n\nBack in 2015 I was working at [skysports.com](https://www.skysports.com/). Each\ntime we pushed code, our continuous integration environment created a clean\nworkspace, installed, configured, and built the latest version of the project,\nthen ran various tests and tasks.\n\nWe were happy with this process and the convenience of npm in particular, but\nthe phase of our builds where `npm install` listed a _huge_ amount of network\ntraffic would always raise the same concerns:\n\n- This seems slow, wasteful, and inefficient.\n- We _really_ depend on registry.npmjs.org, what do we do if it goes down?\n\nThe first suggestion was always to check in the node_modules directory, but the\nidea of large and chatty commits whenever we chose to upgrade or change a\ndependency put us off.\n\nOther teams felt they could live with that and decided to proceed, only to find\nthat packages such as [phantomjs](https://www.npmjs.com/package/phantomjs) and\n[node-sass](https://github.com/sass/node-sass) will helpfully install the\nappropriate binary depending on which operating system you're running.\n\nThis meant that if Chris added `phantomjs` or `node-sass` to the project on his\nMac and checked it into the repository, Helen wouldn't be able to use it on her\nWindows Machine.\n\nThe remaining alternatives were caching proxies or self-hosted registry mirrors,\nand caches-of-sorts. None of which appealed to us and, grudgingly, we continued\nas we were until later creating shrinkpack.\n\n## Justification\n\n\u003e Note: This section was first written in 2015, before lockfiles were the\n\u003e default in npm, pnpm, and yarn. You had to opt-in to using a lockfile by\n\u003e running `npm shrinkwrap` to generate an npm-shrinkwrap.json file.\n\u003e\n\u003e This text has been updated to reflect the situation today, where the need for\n\u003e lockfiles is more widely understood.\n\nWhenever we add, remove, or update an npm dependency — we should test our\napplication for regressions before locking down our dependencies with a\nlockfile. A tagged release should be a locked-down, frozen snapshot of the\ncodebase which has been tested sufficiently enough that it is approved and\ntrusted. When fed into a repeatable, automated deployment process it should\nalways result in the same output.\n\n- Without a lockfile your dependency graph will mutate on a regular basis.\n- Checking in `node_modules` fixes this, but there are some issues which we\n  [discussed earlier](#target-problem).\n- You can be reasonably sure your dependency graph will remain consistent with a\n  lockfile.\n- You can be completely sure with a lockfile _and_ an offline cache.\n\nA lockfile is something I would recommend you use anyway, even if you don't\ndecide to use `shrinkpack`. It increases (but doesn't guarantee) certainty and\nconfidence over exactly what versions of every nested dependency you've tested\nagainst and approved.\n\nWithout a lockfile and an offline cache, that's not guaranteed.\n\nConsider this snippet from the `package.json` of a nested dependency in your\nproject as an example. It's not even a package you directly control, it's a\ndependency of a dependency of a dependency:\n\n```json\n\"dependencies\": {\n  \"lolwut\": \"\u003e=0.1.0\"\n}\n```\n\nIf `lolwut@0.2.4` contains a regression and you're not using a lockfile, your\nproject will contain that regression the next time you install it.\n\n### shrinkpack\n\nWith you hopefully convinced of the merits of lockfiles, `shrinkpack` will\nhopefully be seen as a small and complementary addition.\n\n`shrinkpack` takes the tarballs of the specific dependency graph described by\nyour lockfile and stores them within your project.\n\nThis means;\n\n- No need for repeated requests to registry.npmjs.org.\n- Each package/version pair can be checked in as a single tarball, avoiding\n  commits with all kinds of noisy diffs.\n- Packages can be checked in, while still being installed by members of the team\n  on different operating systems.\n\n## Suitability to your project\n\n`shrinkpack` is best suited to a project which is the root consumer of\ndependencies and not a dependency itself. If your project is intended to be\ninstalled as a dependency of another project using `npm install`, let those\ndownstream projects make their own decisions on bundling.\n\nThat said, if you're developing an npm package and want to use `shrinkpack` to\nspeed up and harden your development and CI environments, adding\n`package-lock.json` and `node_shrinkpack` to your `.npmignore` file will allow\nyou to do that, without publishing your shrinkpacked dependencies to the\nregistry.\n\nIt's not recommended to publish a project with bundled or shrinkpacked\ndependencies to the registry, which would become bloated with duplicate copies\nof packages, bundled amongst various other ones.\n\n## Getting Help\n\n- Get help with issues by creating a\n  [Bug Report](https://github.com/JamieMason/shrinkpack/issues/new?template=bug_report.md).\n- Discuss ideas by opening a\n  [Feature Request](https://github.com/JamieMason/shrinkpack/issues/new?template=feature_request.md).\n","funding_links":["https://github.com/sponsors/JamieMason"],"categories":["Packages","TypeScript","cli"],"sub_categories":["Other"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FJamieMason%2Fshrinkpack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FJamieMason%2Fshrinkpack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FJamieMason%2Fshrinkpack/lists"}