Patrick Desjardins Blog
Patrick Desjardins picture from a conference

TypeScript vs Flow (Part 1 of 3) - Who are they?

Posted on: 2017-08-16

Most of the time, usually at the beginning of a project, some hard decisions need to be made. In the web development world, where JavaScript has the monopoly as a client-side language, the decision is less about the language, but more about the tooling and the libraries to use. However, in recent years JavaScript developers got the option to use language based on JavaScript to increase their productivity. TypeScript was born around 2010 and Microsoft initially released it to the public in October 2012. Facebook alternative named Flow was born two years after TypeScript, almost month to month. Both of them give some rigidity to JavaScript that can be loose in terms of how to write code. Indeed, JavaScript is getting better and better with new features and more support from browsers. That being said, the need to have type or not is a question that could raise lots of discussions. In this article, I will take for granted that the decision about using a typed language has been accepted and that the next step is to figure out which language/static type checker to use, between TypeScript or Flow.

First of all, like any person, I have some bias. I’ve been working in TypeScript since 2014, I never worked with Flow. This is why I did an investigation for two full days and took 30 pages of notes to see deeply the differences I’ll mention during this post, as well as the two upcoming ones when I add opinions instead of facts. Second, what I’m writing here is subject to change over time. The investigation I conducted was done on August 9 and August 10, 2017. It’s a domain where it evolves a lot and my conclusions could change in a few months or years. Third, I could have done an even more thorough investigation with more time. I limited myself to two days.

Concerning my conclusions, here they are; they are both very similar. TypeScript is a transpiler, hence does more. Flow needs Babel to be able to accomplish what TypeScript is Patrick Desjardins 132 doing. Concerning the type checking, they have different mentalities, but are still very similar except for the encapsulation and for the null/undefined validation. TypeScript has 10x the support for third parties, with a vast definition files ecosystem that is not the case for Flow. Now that you have my elevator speech conclusion of TypeScript vs Flow, here are the details.

Historical Background

Flow exists since 18 November 2014. TypeScript exists in public since 1 October 2012, but its inception started 2 years before as an internal product (2010). This information doesn’t give us much other than TypeScript went through more active days of finding bugs, and that Flow may have leverage on the pros and cons of the former. The amount of time between the two is still relatively small, which makes both of them still young.

Flow started at Facebook, TypeScript started at Microsoft. The motivation of Facebook was to create a system that is “sound”[1] while TypeScript is not totally as sound in respect to how JavaScript behaves[2]. Here is a quote from Microsoft TypeScript documentation:

In practice, this sort of error is rare, and allowing this enables many common JavaScript patterns

Microsoft goals and non-goals [17] are well defined. We can read:

Non-goal: Apply a sound or "provably correct" type system. Instead, strike a balance between correctness and productivity.

I’ll provide more examples of what it really means in the next two articles. For this overview, let’s just conclude that TypeScript is closer to JavaScript in some behavior, while Flow is closer to Java or C# by being more strict.

The idea of which one is better is subjective and I won’t go a lot deeper. As a former C# developer, I like the idea of a sound language. As a long-time JavaScript developer and previous PHP developer, I like to have more freedom and can get around how JavaScript handles some behaviors. TypeScript is in the middle, Flow is more on one side. At the end, both help developers in some way to be more protected than vanilla JavaScript. To me, they both win in that category and it wasn’t a criterion that had a significant enough impact to lean me one way or the other.

Definition Files

TypeScript, being the precursor of a superset of JavaScript, brought the notion of the definition file. Definition file allows having typed libraries written in JavaScript. Flow has the same concept, but in a different format, which makes them incompatible, and they never did a conversion to leverage the TypeScript collection. TypeScript started using 2 different ways to store the definition file and ended up storing them with NPM instead of relying on a custom tool. Facebook decided to go with a custom tool.

TypeScript has 3,429 [3] definition files and this doesn’t count a definition file bundled directly in an official JavaScript package. Flow has 302 [4]. Today, getting a definition file for JQuery-UI (250k downloads per month) or Redux-Thunk (1.7 million downloads per month) is not a problem with TypeScript, but it is unavailable with Flow. This is not a big problem if you are using libraries that Flow supports and is not a big deal if you do not need to have types for third parties. Flow could be used to check your own code without having Intellisense for code outside your project. Nevertheless, it is worth mentioning that TypeScript offers more in that aspect and may be more appealing for someone who enjoys having code completion and IntelliSense when coding for custom code as well as code written by someone else.

A small detail about definition files is that Microsoft offers a “pull request mechanism” [5] for a missing definition file as well as accepts a pull request on GitHub. Flow is also accepting a pull request from contributors outside Facebook, but I haven’t found a mechanism to request a library file to Facebook.

At the end, if you are choosing TypeScript you will have all your definition files under the common NPM directory node_module. With Flow, it will be under a folder named flowtyped. It is not a big difference and on balance doesn’t change anything. If I can bring up my personal point of view, I would say that I like that Microsoft went in the existing and wellknown tool NPM and went away from their initial design. Even if it took them three iterations to achieve that goal, it’s now in a place that JavaScript developers know, using a tool that is known and doesn’t depend on a homemade solution.

This had a big impact for me and the team. Being able to use a well-known tool like NPM to reach thousands of types gives us an edge to jump on third parties where we do not know by heart all signatures or potential members. It is something that we thought was a significant decider in our final decision. Again, all depends on your needs.

Open Source

Both projects are open source and hosted on Github. They differ in terms of the license, which is in Flow BSD-3, and in TypeScript is Apache2. I am not a license expert, but from what I know, both are fine. Patrick Desjardins 134 The main difference is the language used. While being open source is great, being able to understand the code is what makes open source greater.

The main point of being open source is to have access to the source code in case something is required to change. The point of being open source is also to get contributions outside the main organization, as well as having a transparent channel to bring in ideas and issues. TypeScript is ahead of Flow about all these particular points. TypeScript source code is easier to read by TypeScript developers because it’s written 100% in TypeScript. Flow is written in OCaml. We do not know exactly the lifespan of each of these products; technologies are changing fast, and both of them may stop being developed at some point. For huge software, this might be an argument in favor of TypeScript, since if in many years they need to do a fix in

TypeScript source code they will be able to do it more easily than having to go in OCaml code. However, this is a borderline case and most of the people won’t mind and that is fair. Still, I think it’s more a positive aspect than a negative one for TypeScript.

Let's bring some metrics around both open source project.

  • Flow has 17 branches, TS has 317
  • Flow has 336 contributors, TS has 228 contributors
  • Flow has 74 release, TS has 48 release (2 months)
  • Flow last month active pull request: 13. TS last month pull request: 188 (July 2017)
  • Flow has 1 057 fork, TS has 3 600 fork
  • Flow has 12 925 stars, TS has 24 738 stars

That’s great, but what can we get from these numbers? I am not an expert on open source projects, but I can only see that there is more activity around TypeScript. The number of contributors and releases are in favor of Flow. That said, the number of contributors is significant only if they are all active. The number of releases is also subjective since TypeScript cadence is every two months, Flow looks to be faster. Does that mean it’s better or not?This is subjective since the balance between stability and new features is always at play. TypeScript has more forks and more starts than Flow. Again, what it really means is that people are more interested, hence follow the project more and maybe get the code. Does it mean TypeScript is better? I don’t think so. The metric that I was the most interested in is the number of pull requests. It’s a good indicator that features and bug fixes are coming in. Both Facebook and Microsoft have employees contributing to the code, but it’s still relevant. TypeScript has more than 10 times the number of features/fixes coming in than Flow.  So, on the open source aspect, TypeScript is one step ahead because of the language used to build it.

What about the future?

The future is hard to know. Microsoft is investing in TypeScript, Facebook is investing in Flow. What I like about TypeScript is that they have an open roadmap [6] available to consult. You can see what they have done and what they are planning to work on. Microsoft also has milestones [7] available in their GitHub account. Flow’s roadmap was not found at the time of this investigation, and no official delivery milestones [8] are available on GitHub. Microsoft has been developing languages since the beginning of the company with a good track record of having long support (10 years after active development). Even Silverlight got a life support by Microsoft up to 2021 [18]!

TypeScript is used by huge projects, and not only from Microsoft. Here is a quick list of companies using TypeScript.

  • Google
  • Slack
  • Asana
  • Ebay
  • Ubisoft
  • Ericsson
  • UpWork (a.k.a Elance)
  • Bloomberg
  • Lyft [19]

And it's used by many projects too.

  • Angular
  • Slack
  • VsCode
  • Teams
  • VSTS
  • Office Web
  • Ionic
  • Blueprint
  • RxJs
  • ReDoc
  • Google TensorBoard
  • Tensorflow Playground
  • NativeScript

Finally, it's praised by tools and frameworks as well.

  • Aurelia framework
  • Ember
  • Babylon.js
  • Laravel
  • MobX
  • ReSharper

But what does that mean and where is the information about Flow? I have to say that I had an easier time finding that list directly from the TypeScript website as well as some blog posts, which are easier to look up. Flow has the disadvantage of having a name that brings lots of noise in search engines. I did some searches but couldn’t find much and their website doesn’t have a list of partners or use cases. But, does having big names in terms of businesses and projects really matter? It does. First, as you can see, Microsoft has quite a few projects written in TypeScript (or that have been converted from JavaScript to TypeScript). You can see that Microsoft Office (Web), Microsoft Teams and VSTS are using TypeScript. These are applications developed by thousands of developers and used by millions of users. Microsoft won’t switch off easily — it would kill the productivity of many projects and won’t be helping Microsoft. For companies and projects outside Microsoft it means that other people had to make the same decision that you may have to make and they analyzed that TypeScript was the right choice. These projects are used also by a lot of people and the decision to go that way was well evaluated. When Google Angular team decided to go with TypeScript instead of Flow or plain JavaScript, they did their homework. It also means that one of these big companies could fork TypeScript and continue its support or development in the eventuality that Microsoft would change its mind.

The future cannot be guaranteed, but TypeScript is written in TypeScript. Visual Studio Code is written in TypeScript. Office (web) is using TypeScript. Microsoft’s new projects, like Microsoft Teams, are written in TypeScript, as well as are their direct competitor’s,who moved to TypeScript. Depending on your project, this should soothe some fears. It’s there in 2017, it will be there in a few years as well. I would like to add more in this section about Flow, but I have limited visibility about Facebook and their plan. It might be as good, but I cannot get anything. Feel free to contact me.

For the moment, concerning the future of TypeScript or Flow, it seems to me that Microsoft has a clearer vision and background of being enterprise solid with their languages.

Developers

In the same way as about language, here is a slight note about who is leading TypeScript. It’s managed by Anders Hejlsberg[9], creator of Turbo Pascal, Delphi, C# and now TypeScript. He graduated in the 80s, received many awards in his career and he is the person who committed the most on Github.

Flow commits are led by Marshall Roch [11] by twice the next biggest contributor, who was the second developer on Flow. I assume that he is in charge of Flow (I might be wrong). He has been for seven years at Facebook and graduated in 2009 from Carnegie Mellon University.

While this might not be a game changer, it’s also a point for TypeScript. The experience behind the lead of this project is a positive for TypeScript. Flow has the advantage to have fresh eyes on new technologies, hence still not bad. At the end, both projects are not driven by a single man, but by a group of people, and are simply influenced by the spirit that leaders project.

Integrations

Visual Studio Code is the prefered language for TypeScript, but they offer a variety of plugin for many IDE. TypeScript and Flow has the same kind of architecture that let external program to communicate with the "local server" to get analyzed for type check. Here is the list of supported IDE for TypeScript [11]:

  • alm.tools
  • Atom
  • CATS
  • Eclipse
  • Emacs
  • NeoVim
  • NetBeans
  • Notepad++
  • Sublime Text
  • Vim
  • Visual Studio
  • Visual Studio Code (VSCode)
  • WebStorm

Here is the list of supported IDE for Flow [12]:

  • Visual Studio Code (VSCode)
  • Atom
  • Nuclide
  • Sublime Text
  • Vim
  • Emacs
  • WebStorm

Beyond the support of IDE, there is the experience of the type checker within the IDE. During this comparison, I used the editor that I use to work on a variety of languages, which is Visual Studio Code (VsCode). The integration with TypeScript is seamless. The integration with Flow requires an extension. This is how VSCode works (1 plugin per language) and it installed flawlessly as well. When starting to convert, I added a comment at the top of each JavaScript file to have Flow catching up on verification. I noticed that when fixing issues, it could take from two to five seconds to have the error getting away from the editor. Flow confirms [13] that VsCode lacks the on-the-fly linting and validates only on save, which is also a limitation on the Nuclide [14] editor that Facebook built.

Both languages have a suggestion when importing custom type which simplifies the writing of the import. However, Visual Studio Code allows with TypeScript to write the code and detect the missing type and auto-suggests which import to bring at the top of the file for you. This is a neat feature that wasn’t triggering while writing with Flow. This might be a limitation of the VsCode plugin.

Again, this might not be a big deal, but if you love one IDE that is not on the list of either Flow or TypeScript, it can become one. Being used to having TypeScript jumping to help me right when I type is also something I was missing with Flow in VsCode. TypeScript covers more IDE, but both are pretty similar in terms of the most popular ones in web development these days. If I had to declare a winner, I would say TypeScript, but with a marginal gain since it supports more IDE. It wasn’t a decisive point for me or the team since the IDE we use were covered.

Support

What about when you have a problem and you need an answer? This will happen and it’s interesting to see what both are offering. Most of the developers will use StackOverflow to write a question to get an answer or will search the Internet and stumble at StackOverflow. If we look at StackOverflow we can see that Flow has 783 questions and TypeScript has 34,613 questions. TypeScript is more active, but we have to put in perspective that people are asking questions about TypeScript the type checker, as well as TypeScript the transpiler. It would be fairer to say that Babel + Flow count would be more comparable. I’ll come back about TypeScript being more than just a type checker in an instant.

About the potential code on the Internet, there are fewer examples in Flow. For example, the well-known TodoMvc has an example with TypeScript and React, TypeScript and Angular, TypeScript and Backbone, but none with Flow.

The official documentation is detailed in both official websites. Very clear, with examples, and both offer an interactive online console where you can drop code and test it.

At the end, TypeScript has a slight advantage. It might be because I was hitting lots of garbage while trying to search “flow” + my keywords but even with “Facebook flow” or “flow js” it wasn’t getting better. I barely found any small projects or websites with good examples with Flow. I found more with TypeScript. However, in both cases, JavaScript’s examples are way higher than the two type checkers we are evaluating.

Beyond Type Checking

During my evaluation of TypeScript vs Flow, rapidly I had to admit that a major difference between the two is that one is doing more than the other. TypeScript is not just a type checker, it’s a transpiler. Flow is a type checker, that’s it.

What is the advantage of Flow? The advantage is that you can use whatever you want for transpiling. To be honest, it means that you will need BabelJs. BabelJs has the advantage against TypeScript that you can cherry-pick plugins and presets you want. TypeScript allows you to enable and disable features, but you are limited to the features they release. At the end, BabelJs is very popular and gives more flexibility. TypeScript is simpler to install and compatibility (or configuration) is a breeze.

I migrated one of my small projects, which is a React project. Here is the TypeScript configuration followed by the BabelJs and Flow configuration.

// tsconfig.json
{
"compilerOptions": {
"target": "es6",
"module": "amd",
"outDir": "./deploy/output",
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"jsx": "react"
},
"include": [
"app/scripts/**/*"
]
}

// NPM packages required
"typescript": "^2.3.2"

Flow and BabelJs:

//.flowconfig
[ignore]
.*/node_moduless/*.*
.*/deploy/*.*
.*/lib/*.*

[include]
.*/app/scripts

[libs]

[lints]

[options]
esproposal.decorators=ignore
esproposal.class_static_fields=ignore
esproposal.class_instance_fields=ignore

//.babelrc
{
"presets": [
"env",
"stage-0",
"react",
"es2015",
"flow"
],
"plugins": [
[
"flow-runtime",
{
"assert": true,
"annotate": true
}
],
"transform-flow-strip-types",
"transform-es2015-arrow-functions",
"Transform-decorators-legacy",
"transform-class-properties"
]
}

// NPM packages required
"flow-bin": "^0.52.0",
"flow-runtime": "^0.14.0",
"babel-cli": "^6.24.1",
"babel-core": "^6.25.0",
"babel-plugin-flow-runtime": "^0.11.1",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-decorators": "^6.24.1",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-plugin-transform-es2015-arrow-functions": "^6.22.0",
"babel-plugin-transform-flow-strip-types": "^6.22.0",
"babel-preset-env": "^1.6.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.24.1"

It has more boilerplate. TypeScript offers stage 2 and up feature from EcmaScript because their philosophy is to have all released feature backward compatible (which is true since version 1.0). Earlier stage EcmaScript features are more prone to die or change signatures. With Babel, you can decide which stage you want to subscribe. This freedom has a cost. TypeScript brings simplicity at the cost of a being a less cutting edge. But what does it really mean at the end? If we look at all EcmaScript 2016 features, Babel is supporting 40% of them, TypeScript 36%. At the end, it's only 2 features different.

It's also interesting to note that BabelJs may support features that Flow doesn't. This doesn't occur with TypeScript since they are in symbios. For example, Flow doesn't support decorator [16], but BabelJs and TypeScript does.

Conclusion

This is part one of three where we put on the table some differences between TypeScript and Flow. If you are reading this article because you are hesitating between the two, stay tuned for the remaining which will be a high and low-level comparison of each of the type checkers. If you are here because you are looking to know if you want typed language vs non-typed language for web development, I would suggest that you consult other sources of data. If you are in some discussions at work about JavaScript vs TypeScript or Flow, I would suggest first deciding between typed or not before jumping on the subject of TypeScript vs Flow. At the end, the goal is not to be a fanboy (fangirl) but to have the best tool that will help you and your team to be productive.

In this article, I illustrated the main difference of TypeScript being more than just a type checker which is a big difference compared to Flow. We also highlighted that the ecosystem around TypeScript is richer with more definition files for third parties. I illustrated that Patrick Desjardins 142 configuring TypeScript is simpler, but that Flow is more configurable. I also briefly mentioned that both solutions have many solutions in terms of IDE. Indeed, after reading only one article of many, it seems that I am leaning more on TypeScript. I would say that the major arguments in the decision about TypeScript or Flow are in fact in that article. The next two articles will bring detail about comparing how both achieve almost the same thing with a very minor difference in terms of features or syntax. At the end, what will matter the most in the choice is the point I brought up here

Parts of the serie:

References

[1] https://discuss.reactjs.org/t/if-typescript-is-so-great-how-come-all-notable-reactjs-projects-use-babel/4887
[2] https://www.typescriptlang.org/docs/handbook/type-compatibility.html
[3] https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types
[4] https://github.com/flowtype/flow-typed/tree/master/definitions/npm
[5] https://github.com/DefinitelyTyped/DefinitelyTyped/labels/Definition%3ARequest
[6] https://github.com/Microsoft/TypeScript/wiki/Roadmap
[7] https://github.com/Microsoft/TypeScript/milestones
[8] https://github.com/facebook/flow/milestones
[9] https://en.wikipedia.org/wiki/Anders_Hejlsberg
[10] https://www.linkedin.com/in/mroch/
[11] https://github.com/Microsoft/TypeScript/wiki/TypeScript-Editor-Support
[12] https://flow.org/en/docs/editors/
[13] https://flow.org/en/docs/editors/vscode/
[14] https://nuclid1e.io/
[15] http://kangax.github.io/compat-table/es2016plus/
[16] https://github.com/facebook/flow/issues/3405
[17] https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals
[18] https://support.microsoft.com/en-us/lifecycle/search?alpha=silver
[19] https://eng.lyft.com/typescript-at-lyft-64f0702346ea