Type-Safe Single Page Apps: F# Vs. TypeScript
Although I did focus on mobile apps in the last years, I've spent the first decade or so of my career concatenating strings, also known as web development. So I think I might know a thing or two about how things work there.
While I respect Elm and Reason, the overall experience seemed very close to web development with F#. Which can also be used for server-side tasks (even code-sharing between client and server is possible). So out of those four, F# and TypeScript are the most serious candidates for me. Sorry Elm. Sorry Reason.
Since finally crossing the chasm in 2017, I am a big fan of the language. As a long-time C# developer, it brought back the joy in programming to me. Making a case for using it in production at a larger scale project would intrigue me.
A Small Case Study
Now, how to make an informed decision that is not solely based on gut feelings? Good question. I decided to conduct a small case study, which I designed to explore three different options to build a type-safe single page application:
In particular, I wanted to find answers to the following questions:
- How are parent-child relationships handled?
- How much boilerplate code needs to be written?
- How much guidance and support provides the compiler?
- How maintainable, aka scalable, does the approach appear to be?
The answers to those questions have already been covered in a separate post. Summary: Going with React components, either with F# or TypeScript, will make you write less code. Whereas choosing MVU (with F# + Elmish) may provide more safeguards through an architecture that is easy to understand and harder to produce errors in.
The bottom line is: Technically, all three approaches are valid, each of them has different strengths and weaknesses. So I cannot recommend one over the other. But I can introduce some more things to consider when making that choice.
More Things To Consider
Code written in F# for me more often than not is concise, easy to write, and even more comfortable to read, containing only very few noisy elements. I sometimes sit in front of my computer and just look at F# code, enjoying its beauty. Seriously, that's probably what sets it apart from most other languages I've had the chance to work with. And it brings literally back the joy in programming to me. That's a factor that cannot be stressed enough, in my opinion. I firmly believe that many bored or almost burned out, but very seasoned developers could quickly be sold on it and "flipped."
TypeScript receives a lot of attention, not only from Microsoft but industry-wide. I don't see a sign that its development might slow down in the foreseeable future.
Similarily, F# has always been supported by Microsoft since its inception, and a (small) team is actively working on it. So there is no reason to worry about the future of the language itself.
The tooling support for TypeScript is just great. For example, it integrates well in Visual Studio Code and is supported by many other editors and IDEs. Several of them are commercially supported.
Whereas the situation for Fable and F# is not that bright at the moment. There is support for a few essential players, e.g., React and Electron. But if you want to use a small random library, you most likely have to create (and maintain!) those bindings by yourself. Which is not a really complicated task – but one that steals time, which could otherwise be spent working on your own project. And if some of the maintainers of the existing bindings lose interest in them, there is a big chance you will inherit them sooner or later (again, see bus factor).
The sheer number of stakeholders makes TypeScript a safe bet for most things, e.g., tooling or library support. It's not only backed and actively developed by Microsoft, but also used by major web frameworks like Angular (Google) and Vue, or at least officially supported (React, Facebook). But it's not only the impressive number of large players. The community also consists of a large number of individual contributors.
Fable, on the other hand, has a small but active community of contributors and a few companies that are backing it (e.g., through SAFE Stack). However, the key drivers of the whole ecosystem are only a dozen or so people who move the entire platform forward in their spare time.
I personally see the chance of reaching the tipping point where the ecosystem might be able to grow faster – but that's totally subjective and possibly more wishful thinking than reality.
The Pit Of Success
The Pit of Success: in stark contrast to a summit, a peak, or a journey across a desert to find victory through many trials and surprises, we want our customers to simply fall into winning practices by using our platform and frameworks. To the extent that we make it easy to get into trouble we fail.
While TypeScript is a tool that integrates smoothly in the JS ecosystem, F# and Fable run on top of it. When using Elmish, JS is the eventual compilation target, and React is the execution layer on which the actual F# application is running without many external dependencies. Given this and the high robustness of the F# compiler plus the reliable guidance by the MVU architecture, it makes Fable and F# a poster child of the idea of the pit of success.
Whereas with TypeScript, every component might look different, depending on its author's taste and level of experience.
There is no doubt that TypeScript is one of the most loved programming languages on earth at the time of writing. So it should not be complicated to find TypeScript developers or train any developer on using it.
While not at all being that popular, I think the story for F# might be more rewarding. There is a large pool of .NET developers who mainly use C# today. A language that adopted and continues to borrow more and more features from F# and that is getting more and more bloated on the way. As already mentioned: I believe that many talented and seasoned C# developers can be trained to use F#. This will make programming more enjoyable to them again and allow you to leverage their experience on the .NET platform.
As you can see, there are valid arguments for both TypeScript and F#. While I can and will not pick a winner at this point, I hope some information in this post can help you to make an informed decision yourself. I am sure it will be the right one! ;-)
What do you think? Drop me a line and let me know!