Third-party software
Our software is built on top of other software developed by other parties, which we often call our dependencies. To ensure that our products are secure, robust, and sustainable, we have two simple rules for how to use third-party software.
- Only use supported software.
- Stay in compliance with the dependency's licensing requirements.
These are our only requirements around third party software. Everything else on this page is informational, providing context, clarity, and tips to help us use third party software effectively.
Supported software
Software is considered "supported" if it is actively maintained by a person, group of people, or organization. The level of support should correlate to its level of impact on our project. For instance, a dependency that provides a critical feature should have more than just an individual maintaining it.
If a dependency is no longer supported or sets an end-of-life date, engineers should bring this up with their team so that they can decide what to do about it and include it in team planning.
Tips for determining support
Determining how well supported software is can be difficult. These heuristics can help us discover the level of support.
For open source projects: review the README, commit history, releases, and open issues to determine how the project is maintained, trying to answer the following questions.
- How is the project is managed and who maintains it?
Projects that have clear governance are much more likely to be reliable than projects that don't explicitly state how they are managed. Be on the lookout for signs that the project may be abandoned, such as growing open issues or an ancient commit history. - When do breaking changes occur?
Nearly all modern open source projects use semantic versioning as their contract for when breaking changes1 happen. Be cautious about projects that don't use semantic versioning unless they provide some other guarantee about breaking changes. - How trustworthy are the maintainers?
We should only use code that we trust. There are many cautionary tales about package maintainers behaving badly, so be very careful about using packages maintained by unknown or suspicious individuals.
For closed source or proprietary projects: review the documentation or reach out to the owner to get a sense of how well supported it is. If a fee is involved, be prepared to make an argument for the cost and why it's worth it over alternatives.
Tips for keeping dependencies up to date
Teams are responsible for keeping their dependencies up to date. Following these tips will help ensure that we don't fall behind.
-
Set a regular cadence for updates. Integrating dependency updates into our regular ceremonies will help avoid having to prioritize it against other concerns. The specific cadence is up to the team, but we recommend at least once a month for most projects.
-
Keep an eye out for end of life. An end-of-life (sometimes EoL) date is a date after which software won't be supported. endoflife.date is a great resource for this since it aggregates many otherwise disparate and sometimes hard-to-find resources.
-
Consider pinning versions. Pinning is the practice of setting an exact version of the dependency that we install. By default, most JavaScript ecosystems pin to the minor version, which works well when the maintainers take semantic versioning contracts seriously. But release mistakes happen, so it's often safest to pin to the version we know works. See Should you Pin your JavaScript Dependencies? for a case for pinning.
-
Follow our decision tree. This decision tree is designed to help a developer update their dependencies one-by-one.
* An update that breaks usage combined with no documentation of the change is a significant warning sign that the maintainers aren't committed to supporting their users. We recommend finding another solution in this case.
Node.js
Node.js is our primary JavaScript runtime language. Because it is one of our lower-level dependencies, security vulnerabilities in it have a greater potential impact and we must keep it up to date.
Thankfully, Node follows a very consistent release schedule, with three phases: "current," "active LTS" (long-term support), and "maintenance." Our software should run on either an active LTS or a maintenance release and should avoid the more unstable "current" releases in production.
To accomplish this, teams should expect to update their Node.js version at least annually, but they may want to be more disciplined about updating.
MongoDB
There are two mostly independent elements to upgrading MongoDB:
- Upgrading the server. Follow https://endoflife.date/mongodb to know when to do this.
- Since we use MongoDB Cloud (the hosted, managed version of MongoDB), this upgrade happens automatically. Teams that use the server need to know when this is going to happen so that they can ensure that their driver is up to date.
- Upgrading the client driver. All drivers can be found at https://www.mongodb.com/docs/drivers/.
- Since most of our apps use Node.js, we can use the MongoDB/Node.js compatibility table to know what version we need to be on based on the version of the server.
Teams should do their best to keep their MongoDB driver version up to date to ensure that they don't need to do anything when the server needs to be upgraded.
Licensing requirements
All software is licensed by its owner, regardless of whether an explicit license exists or whether it is open or closed source. Before using a dependency in our software, we must ensure that we are allowed to use it by carefully reviewing the terms of the license.
- For open source projects: review the LICENSE file in the repository or check the
package.jsonfile (for Node.js projects) to find out what the license is. If no license can be found, it is unlicensed and cannot be used.- Common licenses that are always safe to use include MIT, Apache 2.0, and ISC.
- Avoid licenses that require us to open source our software, such as GPLv33.
- For closed source projects: review the software's terms of use or reach out to the creator/organization that maintains it.
- For projects without a license: do not use unlicensed software, as it is under exclusive copyright of its creator by default, meaning we do not have any permission to use it, even if it is open source.
- If necessary, reach out to its creator to ask them to add a license to the project. Notify your manager if they want to privately license it, as that will require us to involve Norton's contracts team.
Footnotes
-
A breaking change is any change that forces any number of users to make a change. ↩
-
Under semantic versioning, breaking changes can only happen when the major number changes (
X.0.0). Since we know that Node.js follows semantic versioning, we can trust that breaking changes could only possibly happen inv13.0.0andv14.0.0, which is why there's no reason to review any other changes when upgrading fromv12.xtov14.x. ↩ -
Under some very rare circumstances, it might make sense for us to open source a project. Please speak with your manager or the Director of Engineering if you think a project should be open source. All Norton open source projects are currently maintained at https://github.com/wwnorton. ↩