Image for post
Image for post
Photo by Joshua Aragon on Unsplash

Upgrading Flow Codebases

Jordan Brown
Apr 9, 2019 · 5 min read

After releasing v0.85.0, we’ve been receiving a lot of feedback from developers about the difficulty of upgrading Flow in their codebases. This is unfortunate — since then, we’ve added a few new type system features, fixed soundness bugs, improved performance, and improved the Flow developer experience, so staying on old versions is keeping these developers from having a much better Flow experience. In order to help everyone keep their Flow versions up-to-date, we wanted to go over our internal upgrading strategy so that you can figure out the best way for you to upgrade Flow in your repos. In this blog post, we will:

  1. Explain how we upgrade Flow in our giant internal monorepos at Facebook
  2. Justify our upgrade process, which adds a lot of error suppressions
  3. Go over some of the drawbacks of error suppressions
  4. Present resources for learning how to fix errors on ReactRedux’s connect function

Other than the advice on fixing missing annotation errors in v0.85.0, you can apply our upgrade process described here every time you need to upgrade Flow.

Automatically Suppressing New Errors

To use the tool that adds suppressions, you’ll need to clone the Flow repo, navigate to packages/flow-dev-tools and run yarn install. After that, you can use the tool from the root of the Flow repo with ./tool. flow-dev-tools has a few subcommands, but the one that we are interested in is add-comments. For more information on add-comments, run ./tool add-comments --help.

When we upgrade our Flow version, we run:

$ cd /path/to/project$ /path/to/tool add-comments --all --bin /path/to/flow --check check --comment "\$FlowFixMe This comment suppresses an error found when upgrading Flow to v0.xx.0. To view the error, delete this comment and run Flow." .

This command adds a comment with the specified text to every error site in the project. After the command runs, Flow will report no errors.

For example, let’s say your suppression_comment is configured to be:


Suppose you have this foo.js file:

foo.js// @flow
const x: number = "string";

When you run Flow, you get an error pointing to the erroneous assignment. After running the suppression tool, your file would look like this:

foo.js// @flow
/* $FlowFixMe This comment suppresses an error found when upgrading Flow */
const x: number = "string";

… and now running Flow will give you no errors on this file.

Note that flow-dev-tools has a similar command for removing unused error suppressions. We also run this with every release. I recommend running ./tool remove-comments --help for more information on its usage.

Justifying the Coverage Loss

  1. New errors are usually caused by an improvement in Flow’s inference that finds more bugs. v0.85.0 is no different in this respect, and I recommend reading our previous blog post about v0.85.0 for more details. If Flow is not reporting a legitimate error, the coverage is just an illusion. It is better to be aware of the errors than to refrain from upgrading because of the coverage loss.
    That said, Flow errors usually cause an any to be inferred. Flow does this for performance considerations, and to prevent your IDE from getting polluted by downstream errors caused by the bad type. If a new error causes a semi-accurate type to become any, you may lose some actual coverage.
  2. Flow gets better with each release, so staying behind will keep you from reaping the new benefits. A few concrete changes that have landed (with blog posts) since v0.85.0 were improved React support via React.AbstractComponent and a dramatic improvement to the Flow dev experience with parallelizable commands.
    It’s also worth noting that the annotations required by v0.85.0 will be necessary to power the eventual replacement for gen-flow-files.
  3. Delaying an upgrade doesn’t make it easier. Most new Flow versions come with new errors, so staying behind will only enlarge the set of errors you need to address in order to get caught up.

And remember, Flow was built for incremental adoption, so partial coverage is something Flow is good at!

The Downside of Suppressions

  1. If a suppression appears directly above any of the lines mentioned in an error message (not just the main one), then the error is suppressed. If the line under a suppression is mentioned in the blame of a new error later, then the new error will also be suppressed.
  2. Suppressions will suppress every error on the line directly below it. So if you suppress an error and then make a change that causes a new error on the same line, then the suppression may hide this new error from you.

These bad side-effects are rare, but they do happen in practice. The Flow team has started to discuss changes to how suppressions work in order to prevent these side-effects.

Fixing Errors with ReactRedux’s connect Function

Later, Ville Saukkonen, one of the maintainers of flow-typed, made instructions to fix errors on connected components. His repo is using ReactRedux 5 and Redux 3.6, but his advice applies to ReactRedux 4.x.x as well. You can check out those instructions in this gist. When Ville was upgrading’s codebases to v0.85.0, he included a shortened link to his gist in the suppression comment so that developers at could easily get instructions to fix the errors — you may want to consider doing the same! Incentivizing developers to fix Flow suppressions can be hard, so making it as easy as possible to fix them will be worth the investment.

That’s All!

Further Reading


The official publication for the Flow static type checker…

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store