Rob Bearman
February 8, 2016

Basic Web Components is a monorepo

Basic Web Components (BWC) is a project containing multiple, often-related Web Components along with support code implemented as mixins. As we have migrated the implementation of BWC from Polymer components to a plain JavaScript approach, we’ve also revisited the way we organize the project to support the following goals:

These requirements depend somewhat on our decision to use npm version 3 and its support for flat directory installation of dependencies, rather than Bower. We believe that centralizing distribution and discoverability of Web Components in npm has been a long desired goal, hindered only by npm’s lack of support for Bower’s flat/peer folder installation. With npm version 3, we now have that along with npm’s greater developer mindshare and support. npm version 3 is a big win for the Web Components community.

The BWC project's needs boil down to two main issues. The project needs to be maintained as a single Git repository, and multiple packages destined for publication to npm are defined within the repository. We chose to organize BWC as a monorepo in order to support these goals. A monorepo can be thought of as multiple independent software projects contained within a single Git repository. You can see other projects that rely on the monorepo approach by reading the Babel team's reasoning for organizing its project as a monorepo.

We actually took steps towards a monorepo in our previous major version of BWC. We had identified the benefit in having all components and support code available in one directory tree for development and testing purposes. But instead of associating each Bower/npm-published component with the common repository, we created separate Git repositories for each component and built scripts that pushed changes from the consolidated repository to the individual component repositories. A consumer of a component could install from Bower or npm by passing along the Git repository’s master branch URL, or a version-tagged commit URL. The scripts to push to Git and set new version-tagged releases were onerous and confusing. A common question became whether contributors should work on the consolidated repository, or on the individual component repository.

By moving to a monorepo, there’s no longer a question of where work should be done. All work is done on code within the BWC monorepo. We maintain a monorepo policy of updating, after the completion of significant work, all contained components to the same npm version, with each package in the monorepo having its own package.json. A Grunt task publishes each package in the monorepo to npm. While there are individual Basic Web Components npm packages registered with and searchable from npm, there is only one Git repository representing the code behind these packages. And because the individual component packages within the monorepo are contained within peer-adjacent filesystem folders, the monorepo development environment mirrors an npm installation of the components.

One of the benefits of this approach is the shared, reproducible development environment we get by having all packages depend on the same root project package.json, coupled with an npm-shrinkwrap.json file that ensures each developer’s run of npm install against a clone of the BWC monorepo results in the same node_modules folder contents. This eliminates third-party version issues that may introduce errors or side effects that are not reproducible across development environments.

As we develop new components and mixins for the Basic Web Components project, watch for them as new directories under the BWC monorepo’s packages folder.


« Blog home