Vetting Third-Party Components

Kris Zyp
Doctor Evidence Development
3 min readJan 23, 2018

--

JavaScript’s meteoric rise, alongside the exponential growth of the NPM ecosystem, has given JavaScript developers unprecedented opportunities to use a rich variety of packages. But this is a luxury that we can also easily over-indulge in. A couple years ago, the left-pad removal left thousands of project builds broken, despite it being just a few lines of code. Recently a great post about the how easily security can be exploited through NPM packages has been widely read. We have also experienced pain when a dependency suddenly decided to add a polyfill that conflicted with our polyfills. More dependencies means an increased risk of breakage and broader surface area to security exploits and vulnerabilities.

The addition of each new third-party package carries the potential for negative externalities — unintended problems and harmful side-effects. A package may seem expedient for solving an immediate issue, but every package has subtle impacts on the rest of the application. The cumulative effect of numerous packages leads to greater memory consumption, slowed performance, and new security vulnerabilities which can damage the experience and safety of your users. On the development side, additional packages can add more application complexity, introduce challenges in dependency management, and encourage anti-patterns or unnecessary crutches that require constant maintenance and slow development. There are tremendous benefits to be reaped from the huge ecosystem of packages, but the real cost of each dependency must be weighed.

We have put substantial work into minimizing the complexity and interdependencies of the Doctor Evidence code base, but there are plenty of packages that we depend on and use to great benefit. Maintaining a minimum of dependencies requires discipline, and consequently we have put together guidelines to review before the addition of any new packages.

Guidelines

Before adding any third party package or component, the following questions should be addressed, and the proposed addition should be reviewed and vetted by our engineers. Note that adding development dependencies for testing, building, or other dev activities, should still involve some consideration, but does not require nearly the level of review, since it won’t involve loading code in production.

What is its file size?

How is it loaded?

  • Does the component need to load in the initial page load? Will it be in our webpack bundles? Can some or all be deferred? Does it load additional resources (images, stylesheets, fonts)? Can these be bundled?
  • Does this require binary compilation? (for Node)

Is it loaded from a third-party server?

  • If any code is sent, do we trust this company with access to all our data?
  • Do we have any mitigations for code changes on their end?
  • How will the application respond when the third-party server is down or inaccessible?

What are its dependencies?

  • Does this have transitive dependencies that also add weight? Are any of the transitive dependencies already loaded/shared? There is no strict cutoff requirement here, but for comparison sake, most “major” new features at Doctor Evidence (involving mock-ups, substantial planning, etc.) have added less than 50Kb to the front-end application. Dependencies larger than that will require more justification.

What is its performance cost?

  • How much time is required for script evaluation? How much time for initialization and rendering? For comparison, most major new features on our platform add less than 20ms of evaluation time, and when actually used/rendered, render in less than 500ms.
  • What is the memory cost? How much additional memory is required?

What interactions does it have with the application environment?

  • Does this alter any globals or constructs in the environment? Does this load any polyfills that alter existing objects?

Are there security vulnerabilities?

  • Does the component do any assignment of potentially user-provided data to innerHTML or other code executing properties (without escaping)?

Does its functionality overlap with an existing component?

  • In what ways does the existing component fail to provide the necessary functionality? Can it be altered or extended to fulfill the need?

These are the guidelines we’ve used at Doctor Evidence to keep our application lean, stable, and easily maintained.

If you are interested in building powerful tools for medical research without having to learn an endless stack of packages, learn more here.

--

--