Getting to grips with Flow

– 4 minutes read – Frontend Engineering

In collaboration with Martin van Dam

The last few years we’ve seen the rise of typed languages in the frontend, increasing both readability of code and preventing possible bugs and issues. TypeScript comes to mind when you’ve touched Angular (not to be confused with AngularJS) and even if you’re leaning more towards React, where TypeScript support is improving. However, we feel that it’s important to know what competition is out there and if it has any aces up its sleeve.

In this article, we describe our findings after playing around with Flow and looking up any considerable differences between the Flow type system and TypeScript, our current go-to option.


If you’ve used TypeScript before with VSCode, you may need to adjust some settings to stop VSCode from bothering you (e.g. ‘Types can only be used in files with a .ts extension’). You can disable TypeScript permanently or for just your Flow workspace, by disabling javascript.validate.enable in your settings.


There are two options for compilation to get from the current Flow syntax back to valid JavaScript that your browser will accept.


This one is quite literal in it’s function. It literally removes the type syntax that Flow uses. Fun fact: It leaves spaces where the type info used to be, so it does more of a replace than anything else.

function foo(x         )         {
	if (x) {
		return x;
	return "default string";
class Test {	             
	constructor(name        )       { = name;

(Yes, the extra spaces are actually in the build artifact as generated by flow-remove-types).


Babel is about as straightforward to setup, with one additional configuration file to add, .babelrc:

	"presets": ["flow"]

And from there it’s the same thing: babel src/ -d dist-babel/

This one does clean up the spaces neatly.

Import / Export

Exporting a type is as you would expect: export opaque type FileID = string

Importing is a bit different, import { type FileID} from './index', if you forget the type in this part; it will complain about using it as a value instead of a type.


Predicate Functions

Adds the %checks syntax to a function. Its return value is then used by the compiler to make non-null assumptions of variables. This is currently not available in TypeScript. Limited class access modifiers

In Flow there are no (known) ways to indicate private or public functions or variables. This is something that’s very dominantly available in TypeScript. Although it doesn’t affect the runtime at all (the access modifiers are removed after compilation), it’s a step that does increase readability and describe intent of code. Considering Flow is trying to live more closely to the original JavaScript, it makes sense that they don’t have any support for this. At least not until ECMAScript starts supporting this. Conclusion

Flow is more of a small layer on top of your code. In the end you’re still writing raw JavaScript but mixing in the Flow specific type syntax.

TypeScript is a separate language, it extends JavaScript. It has its own file extension, .ts which makes it very clear that it’s not raw JavaScript. One could argue that you could do the same with Flow’s files of course. A con of TypeScript in our opinion is that your code is transformed into garbled up JavaScript that is hardly human-readable anymore. You all of a sudden require SourceMaps to make your code readable and debuggable, where with Flow you’re just running with raw Javascript.

It’s a matter of taste. Flow definitely is easy to setup (although VSCode is a bit TypeScript biased) and has little effect in your build process, where TypeScript is a full on superset and therefore a different language.

In our opinion, we would always choose TypeScript over Flow, but not because we think Flow is a worse solution. It’s a matter of preference and what you’re used to working with. What we all agree on, is that working with statically typed languages to produce your front-end JavaScript, is always recommended and a good thing.