Blog

How to migrate away from Bower?

If you came here because of “Request to xxx failed with 410” error, it’s enough to upgrade

As you might have noticed, we started recommending Yarn as an alternative to Bower for new front-end projects. Main reasons are straightforward and written on its home page:

  1. Yarn uses checksums to verify the integrity of every installed package (like npm@5)
  2. Yarn uses lockfile to exactly reproduce installed packages each time (like npm@5)
  3. Yarn supports most features npm supports, and is able to force flattening of dependencies

So far it just wasn’t obvious how one could use Yarn for legacy Bower projects. Indeed, until recently Yarn neither could install Bower packages (i.e. GitHub repositories without package.json) nor resolve semver ranges on git tags. I focused on this for a while and the result is pleasing: Yarn 1.x is able to install most of Bower packages. But there’s a catch: it cannot resolve Bower dependencies.

But this is probably for the best as a) Yarn is meant as npm’s replacement b) one must admit npm’s CommonJS module ecosystem is better integrated than Bower’s globals/AMD modules c) Module authors currently suffer from supporting two module ecosystems (and dist files in repositories).

Admitting this doesn’t change the fact that it’s difficult to migrate a project that uses globals/AMD components to CommonJS all at once. Ideally you’d be able to install such project with Yarn as-is, and only then gradually replace AMD modules with CommonJS/ES6 equivalents. Solution: bower-away.

How it works?

Yarn is not only unable to resolve dependencies of Bower components (i.e. dependencies defined in bower.json, it looks just for ones in package.json), it also cannot translate names of Bower components to URLs of repositories as described in previous blogpost. bower-away gets away with this by resolving all dependencies with Bower, and adding all of them flattened to package.json.

The result is something as follows:

{
  "dependencies": {
    "@bower_components/almond" : "jrburke/almond#~0.2.9",
    "@bower_components/angular" : "angular/bower-angular#^1.0.8",
    "@bower_components/d3" : "mbostock-bower/d3-bower#~3.3.10"
  }
}

Now, if you install this package.json with Yarn, node_modules/@bower_components will contain all components in exactly the same way they would be installed by Bower (sans generated .bower.json).

And not only that, if some component supports CommonJS interface, you can employ Webpack for precompiling and require it as so: const almond = require('@bower_components/almond').

For components that don’t support CommonJS, you can find their CommonJS equivalents and add them to project: yarn add d3@~3.3.10, then require as usual const d3 = require('d3')

But initially, the only change required in code is to change any reference to bower_components with node_modules/@bower_components (though you can link it somewhere else in postinstall script).


If you have any questions or find any issues with this script, please post issue at bower-away repository.

How to drop Bower support?

From time to time I get asked how to drop Bower support as an owner of JavaScript module as so developers who already use this module (in both applications and other modules) won’t get mad at you.

This procedure is as follows:

  1. Before, notify all users of your module who might be affected by this change (see below)
  2. Remove all distribution files and bower.json from repository
  3. Tag repository with new major semver version (e.g from 3.5.6 to 4.0.0)
  4. Don’t remove your component from Bower registry (via bower unregister)

To understand why these steps are necessary you need to know how Bower resolves components.

Why step 4?

When Bower sees module name in dependencies of bower.json, it tries to resolve it to repository URL by consulting the only centralized part of Bower: its registry. The registry is not as advanced as npm’s. It is a simple mapping from module name to URL of module’s repository. E.g. for jquery:

{"name":"jquery","url":"https://github.com/jquery/jquery-dist.git"}

Bower consults for this information upon each installation (but caches result for some time). It is because it lacks locking known from Yarn and introduced in npm. If you remove this entry, then modules and apps that depend on your module will fail to install. So please don’t unregister your component.

Why step 3?

Because removing support for something is a breaking change. But also because Bower depends solely on git/svn tags for version resolution (it doesn’t care what version is in bower.json, you can remove it).

If someone reasonably specified "yourpackage": "^2.3.5" as a dependency, removing support for Bower in 2.4.0 would break her installation. Instead, bump major semver version, and tag it 3.0.0.

Why step 1?

Removing bower.json and distribution files breaks all installations that specify in dependcies "yourpackage": "*" (more likely, resolves to latest semver tag) or "yourpackage": "master" (less likely, resolves to latest change on master branch). In such case Bower will resolve versions of your package that don’t support Bower. Honestly this is a fault of these developers for not properly using semver ranges for dependencies, but be considerate and notify them to update dependencies in their packages few weeks before dropping Bower support.

Thanks to libraries.io you can fairly easy discover these developers at:

(please replace mocha with your module name)

You can go to these repositories and create issues / PRs that ask to commit (tagged!) patches, ideally for each major version, so these modules depend on proper semver range of your module, and not *.

You can also notify developers on social channels, because libraries.io won’t list private apps.


Do you think I missed something? Please comment on #2482

Using Bower with Yarn

UPDATE: Yarn decided to drop Bower support for now. We recommend to try it anyway as an alternative to npm!

Yesterday’s official release of Yarn adds an interesting new tool to the world of package managers, bridging the gap between Bower and npm, and adding the most requested features to both.

Yarn looks like a great improvement compared to the current Bower client in a number of ways we’ll describe. It could help you to transition to npm if that is something you’ve been looking for recently.

As Yarn already supports multiple package formats and ecosystems, we secretly hope it will empower JavaScript developers to further develop the ES6 modules ecosystem, as compared to CommonJS used by the npm community, and AMD/globals used by Bower’s community. Browsers and node agree.

Yarn advertises itself as a drop-in replacement for both npm and Bower. This means you will be able to continue using your existing bower.json just like before. Yarn installs bower components to bower_components, npm components to node_modules, and supports dependency flattening!

Important note: As it stands right now there still seem to be some issues regarding Bower support. We are however confident that with the help of the community, these issues will be solved quickly as Yarn steps towards 1.0 in upcoming months.

It is important to keep in mind that just like npm, Bower consists of more than just the CLI component and switching between the npm and Bower ecosystem can still be improved in a number of ways.

Take a quick look at some more goodies that Yarn has to offer:

Lockfile

Faithful users of Bower will be very pleased to see that Yarn adds the long awaited Lockfile feature with even stricter reproducability across devices and systems than npm offers at the moment.

Security

Checking each package against checksum before they are installed guarantees a certain degree of integrity, and gives the developer more confidence from a security standpoint.

Speed and offline

Yarn’s cache is a pretty elaborate improvement over what Bower had to offer so far, reducing (cold) install times by a great deal and even more so in a cached scenario. At the same time it allows complete installs even without an internet connection!

Licenses

The ability to list a dependencies’ license type is often required in enterprise environments. Yarn offers an easy way to list the license type for a given dependency.

Welcome!

You can read more about Yarn in Facebook’s post. Together with npm, we thank the Yarn team for developing it (especially Sebastian). We look for fruitful cooperation.

What’s new in bower

The bower team has been working hard, getting new features in the project and closing bugs for users and developers. As of 2016–04–05, bower is version 1.7.9.

My favorite one is the option to have —save enabled with every download, as described here 1040, usually when I’m adding a bower dependency I’d like it to be saved on the bower.json, very rarely I would download a package with no project.

Backwards compatibility is important, so by default this is disabled, to enable it add the options “save” and/or “save-exact” to your .bowerrc configuration file.

{
  "save": true,
  "save-exact": true,
}

With save-exact, the version will be persisted to your bower.json, like this:

{
  "angular": "^1.5.3",
  "bootstrap": "3.0.0"
}

All the new features added this month are:

1.7.9–2016–04–05

  • Show warnings for invalid bower.json fields
  • Update bower-json
  • Less strict validation on package name (allow spaces, slashes, and “@”)

1.7.8–2016–04–04

  • Don’t ask for git credentials in non-interactive session, fixes #956 #1009
  • Prevent swallowing exceptions with programmatic api, fixes #2187
  • Update graceful-fs to 4.x in all dependences, fixes nodejs/node#5213
  • Resolve pluggable resolvers using cwd and fallback to global modules, fixes #1919
  • Upgrade handlebars to 4.0.5, closes #2195
  • Replace all % chatacters in defined scripts, instead of only first one, fixes #2174
  • Update opn package to fix issues with “bower open” command on Windows
  • Update bower-config
  • Do not interpolate environment variables in script hooks, fixes bower/config#47
  • Update bower-json
  • Validate package name more strictly and allow only latin letters, dots, dashes and underscores
  • Add support for “save” and “save-exact” in .bowerrc, #2161

The whole list of changes can be found here.

Update on recent changes

Bower has seen some smaller updates over the past months and while some of those were really challenging to get right, they bring a lot of improvements. Let’s take a look at some of the things that changed and improved.

A small but important update was the change of our default —-save operator, which used to be the tilde (~) and has now been changed to the caret (^). That way Bower will be more inclusive for minor version updates, as you would expect. As usual this was a non-breaking change, so all packages using a tilde for versions still continue to work.

We removed analytics from Bower! This is a pretty big one, as it was a much requested change that could lead to a break of automated uses of Bower, such as Travis CI builds. While you would be asked „May bower anonymously report usage statistics to improve the tool over time? (Y/n)“ upon using Bower for the first time, Bower is now completely silent in that regard. That being said, we’re also looking to replace the statistics we collect with some more meaningful data and already dropped the command-usage overview, as it is not useful to us or our users.

Bower is now distributed with npm3. This was mainly needed due to a bug on Windows, where paths could become too long for the OS to handle. Especially the bundledDependencies gave us a headache in this situation, however npm3 solves this by using a flat structure, resulting in smaller paths.

Paths in the .bowerrc configuration can now be absolute instead of only relative, which makes it easier and is what you might expect.

We also learned that people are requiring files from Bower’s core more or less randomly, which forced us to release version 1.7.6 and 1.7.7 quickly after 1.7.5 so builds didn’t break. In general there is only one correct way to use Bower programmatically and that is require(‘bower’). Relying on any specific file from Bower that is subject to change is never a great idea!

Apart from those changes there were many more bugfixes, small changes and documentation updates throughout the past months. Check the changelog for a more detailed overview. You can get all those updates and bugfixes by updating Bower via npm install -g bower.

We already have some great commits for the upcoming version and are always happy to see new people contributing. Step by in our Discord channel or directly over at GitHub.