Using Bower’s resolutions field to pin dependency versions in legacy front‑end projects
Learn how Bower’s resolutions field turns interactive version conflicts into deterministic, CI‑friendly installs—and what trade‑offs to watch for in legacy front‑end projects.
27 Aug 2026, 16:30 UTC

The problem: Bower stops at a version conflict
When you maintain a project that still relies on Bower, adding a new front‑end library often triggers an interactive prompt:
Unable to find a suitable version for jquery, please choose one:
1) jquery#2.2.4
2) jquery#3.5.1
This happens because Bower enforces a flat dependency tree: only one version of a given package may exist in bower_components. If two dependencies declare incompatible ranges, Bower refuses to guess and asks you to decide.
Thesis: the resolutions field makes the decision explicit and repeatable
Bower provides an escape hatch called the resolutions field in bower.json. By declaring which version should win a conflict, you turn an interactive prompt into a deterministic, CI‑friendly install. The field does not change how Bower resolves dependencies; it simply records the winner you chose.
Worked example: pinning jQuery
Suppose your application depends on jquery^3.0 while a legacy plugin you need declares jquery^2.2. The bower.json before adding resolutions looks like this:
{
"name": "my‑legacy‑app",
"dependencies": {
"jquery": "^3.0",
"old‑plugin": "git+https://github.com/example/old-plugin#v1.0"
}
}
Running bower install in a clean folder yields the prompt shown above. To make the install non‑interactive, add a resolutions section that pins jQuery to the version you want to keep (here, 3.x):
{
"name": "my‑legacy‑app",
"dependencies": {
"jquery": "^3.0",
"old‑plugin": "git+https://github.com/example/old-plugin#v1.0"
},
"resolutions": {
"jquery": "3.5.1"
}
}
Now bower install proceeds without asking for input. You can verify the result by checking the installed version:
bower list jquery
The output should show jquery#3.5.1 in bower_components. At this point you must test whether the old plugin still works with jQuery 3.x; if it relies on removed APIs (e.g., .andSelf()), you will see runtime errors.
Trade‑offs and limitations
- Pinning is a decision, not an automatic fix. Choosing a version may silently break a dependency that needs the older range.
- Bower has no lockfile. Reproducibility relies on committing exact versions in
bower.json(includingresolutions) or vendoring the wholebower_componentsdirectory. - The project is in maintenance mode; the registry still responds, but no new features are expected. For new work, the maintainers recommend npm or Yarn.
Practical verification steps
- In a disposable directory, run
bower installand confirm the prompt appears. - Add the
resolutionsfield as shown, then runbower installagain. The command should finish without asking for input. - Check the installed version with
bower list <package>. - Run your application’s test suite or manually load the page to ensure the pinned version does not break existing functionality.
Actionable closing
If you are maintaining a legacy Bower‑based codebase, treat the resolutions field as the place to record version decisions you have already validated. Commit the field alongside your bower.json so that every teammate and CI pipeline gets the same, non‑interactive install. When the cost of testing a pinned version outweighs the benefit, consider migrating the dependency to npm or Yarn, or fork the library to a version compatible with your chosen jQuery line. Until then, let resolutions make your installs predictable, not surprising.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.