Dependency Management Guidelines

This repository uses third-party code from a variety of sources, so we need to be mindful of how these dependencies will affect our consumers. Considerations include:

We're still evolving our policies in this area, but these are the guidelines we've developed so far.

Rust Code

Unlike Firefox, we do not vendor third-party source code directly into the repository. Instead we rely on Cargo.lock and its hash validation to ensure that each build uses an identical copy of all third-party crates. These are the measures we use for ongoing maintence of our existing dependencies:

  • Check Cargo.lock into the repository.
  • Generate built artifacts using the --locked flag to cargo build, as an additional assurance that the existing Cargo.lock will be respected.
  • Regularly run cargo-audit in CI to alert us to security problems in our dependencies.
    • It runs on every PR, and once per hour on the main branch
  • Use a home-grown tool to generate a summary of dependency licenses and to check them for compatibility with MPL-2.0.
    • Check these summaries into the repository and have CI alert on unexpected changes, to guard against pulling in new versions of a dependency under a different license.

Adding a new dependency, whether we like it or not, is a big deal - that dependency and everything it brings with it will become part of Firefox-branded products that we ship to end users. We try to balance this responsibility against the many benefits of using existing code, as follows:

  • In general, be conservative in adding new third-party dependencies.
    • For trivial functionality, consider just writing it yourself. Remember the cautionary tale of left-pad.
    • Check if we already have a crate in our dependency tree that can provide the needed functionality.
  • Prefer crates that have a a high level of due-diligence already applied, such as:
  • Check that it is clearly licensed and is MPL-2.0 compatible.
  • Take the time to investigate the crate's source and ensure it is suitably high-quality.
    • Be especially wary of uses of unsafe, or of code that is unusually resource-intensive to build.
    • Dev dependencies do not require as much scrutiny as dependencies that will ship in consuming applications, but should still be given some thought.
      • There is still the potential for supply-chain compromise with dev dependencies!
  • As part of the PR that introduces the new dependency:

Updating to new versions of existing dependencies is a normal part of software development and is not accompanied by any particular ceremony.

Android/Kotlin Code

We currently depend only on the following Kotlin dependencies:

We currently depend on the following developer dependencies in the Kotlin codebase, but they do not get included in built distribution files:

  • detekt
  • ktlint

No additional Kotlin dependencies should be added to the project unless absolutely necessary.

iOS/Swift Code

We currently do not depend on any Swift dependencies. And no Swift dependencies should be added to the project unless absolutely necessary.

Other Code

We currently depend on local builds of the following system dependencies:

No additional system dependencies should be added to the project unless absolutely necessary.