Using Bower Shrinkwrap to Lock Front‑End Dependencies for Deterministic Builds
Learn how to generate, commit, and use Bower’s shrinkwrap file to keep every team member and CI environment installing the exact same package revisions, ensuring reproducible builds.
21 Mar 2026, 01:42 UTC

Problem
Front‑end projects that rely on Bower often face a subtle but serious issue: running bower install on different machines or at different times can pull in newer revisions of a package that satisfy the version range in bower.json>. This drift breaks tests, introduces bugs, and makes debugging difficult.
Why Shrinkwrap Matters
Bower’s shrinkwrap feature records the exact Git revision (or tag) for every dependency, direct and transitive. When bower install is executed, Bower consults bower-shrinkwrap.json first, overriding any ranges in bower.json>. The result is a deterministic dependency tree that all developers and CI pipelines share.
Prerequisites
- A project that already uses Bower and has a populated
bower.jsonfile. - Node.js and Bower installed globally (e.g.,
npm install -g bower). - Git repository with a clean working directory.
Creating a Shrinkwrap
- From the project root, run:
This installs the current dependency tree.bower install - Generate the shrinkwrap file:
The command writes abower shrinkwrapbower-shrinkwrap.jsonthat maps each dependency to a specific Git commit or tag. - Review the file to confirm that revisions match the packages you expect. For example:
You should see a commit SHA next tocat bower-shrinkwrap.json | grep jqueryjquery.
Committing the File
Because the shrinkwrap file is source‑controlled, every clone of the repository will use the same dependency tree. Add and commit it:
git add bower-shrinkwrap.json
git commit -m "Add Bower shrinkwrap for deterministic installs"
Using Shrinkwrap in CI
In a CI job (e.g., Jenkins, GitHub Actions), simply run bower install. Bower will honor the shrinkwrap automatically. Example GitHub Actions step:
- name: Install Bower dependencies
run: bower install --allow-root
env:
BOWER_CONFIG: "/dev/null" # avoid local config overrides
Verifying Determinism
- Clone the repo on a fresh machine.
git clone https://example.com/repo.git cd repo bower install - Check that the installed revision matches the one recorded. For instance, verify the Git commit of
jquery:
The SHA should match the one incd bower_components/jquery git log -1 --pretty=format:%Hbower-shrinkwrap.json. - To test that the shrinkwrap overrides
bower.json, editbower.jsonto a newer range (e.g., "jquery": "^3.5.0"), runbower installagain, and confirm that the installed revision remains the same as before.
Common Pitfalls
- Missing shrinkwrap in CI: If the shrinkwrap file is not checked in, the CI will install whatever satisfies the ranges, defeating the purpose.
- Manual edits to
bower.jsonwithout regenerating: Changing a version range may break the shrinkwrap. Runbower shrinkwrapafter any update. - Using Bower post‑deprecation: Bower is no longer maintained. Consider migrating to npm or Yarn for new projects.
Recovery & Updates
When a dependency needs to be updated (e.g., a security patch), follow these steps:
- Run
bower install <package>#<new-tag-or-commit>to fetch the desired revision intobower_components. - Commit the updated package folder and the new
bower-shrinkwrap.json.git add bower_components/jquery bower-shrinkwrap.json git commit -m "Update jquery to 3.5.1" - Push and run CI to verify that the new revision is installed everywhere.
Limitations & Future Outlook
Because Bower is officially deprecated, future releases may drop shrinkwrap support. The technique remains viable for legacy projects that cannot immediately migrate. For new projects, consider using npm’s package-lock.json or Yarn’s yarn.lock to achieve the same determinism.
By committing bower-shrinkwrap.json and following the steps above, teams can eliminate the “works on my machine” problem and guarantee that every build uses the exact same dependency tree.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.