Making the case for Elm at my company. Looking for help!

In my mind there are multiple reasons that make Elm superior to React + TypeScript. Elm does not only give you static type checking. You’re also getting:

  • purity - the compiler makes it impossible to write code that depends on hidden inputs / implicit state, or secretly modifies some state somewhere. You have to provide what you depend on via function arguments, and if you want to “modify” something you have to create new copy of it and return it as return value. This sounds like more work, but it makes things visible to the compiler and doing that you’re exposing more things to the compiler to check for you.
  • sum types (or variant types, not sure how elm community calls them now) and pattern matching. This makes it possible to model business-domain / constraints precisely and make it impossible to represent invalid states. This together with exhaustiveness checking (am I handling all cases in all places that use this data type?) eliminates significant class of bugs.
  • immutability - whenever you want to change something, you have to create new copy from the original that you’re changing. You can try to achieve something similar in JS too by using libraries, but there’s nobody checking for you that you (or a new colleague joining your team) is going to use that consistently across the entire code base.

The end result is that if you can say “My code compiles” you’re getting much more guarantees in Elm then in TS/React.


Hello! Since you are listing Elm meetups in your document, we also have a pretty good Elm meet up here in Munich! :

One argument I like, is how easy it is to refactor. So naturally, as businesses learn more about their customers and thinks more on how to serve them, projects and products need to change in unexpected and fundamental ways. Thats just life, as far as I can tell.

But suppose you have a huge React project, and one of these unexpected changes comes along. What can you do? Well, if you make a fundamental change somewhere, the only consequence is that your code is going to break in many places. Some parts of the code will be changed, but other unknown parts wont line up and youll just have errors. The only way to grow big react projects is just to burn them down and rebuild because you cant make fundamental improvements that outweigh the bugs youll be introducing.

In a big Elm project, you can change fundamental parts of you application no problem. If things dont line up, it wont compile. Like, at work our Elm code base is 80k lines, and recently I had to change some really fundamental stuff about how we were handling authentication and local storage. It was a big change that touched a lot of files, and after two days of continuous refactoring, there were no resulting errors. Merging was not only pain free, but it was so innocous no one even noticed. I didnt have to be on pager duty for when the product blows up, we didnt need extensive QA testing; none of that. It was great.

Ive did one TypeScript + React / Redux project on a team with two other developers. Heres my impression of how we did TypeScript, which I think aligns well with theirs too:

  1. It was surprisingly not that functional. We used Ramda in the project, but, the hassle of using it was pretty high.
  2. The type system is a lot more like that of Java than that of Haskell. The TypeScript code for making the practical equivalent of a custom type in Elm, is 5x as much code, and pretty ugly.
  3. Types arent native to JS, so all TS types are just bolted on as an after thought. That has two implications. Firstly, they arent fully reliable. Theres some JavaScript data, and people take their best guess as to how it should be typed in TypeScript, and naturally they are only 95% reliable in their typing. Secondly, the types can be enormously complicated and include tons of internal implementation details. Whenever I had a type problem with some Redux component, my terminal would just be lines and lines of red spagetti.

Yep. I’m already pushing some of those types of constraints in our TS code via TSLint. Like @Chadtech said, it is possible to enforce those things, but TS isn’t made for it. That said, I think my team wouldn’t be enthusiastic enough about Elm to deal with ports, so I’m considering Reason as a compromise.

I’ll keep playing with Elm on the side though, and maybe I’ll be able to introduce it properly at work someday.

I haven’t use Typescript in a big project, but we started our application with Flow + React. It is quite disappointing:

With Flow:

  • Not all libraries have definition or good ones, you end up with type black holes, places where the checker just doesn’t know what a thing is, so all the checking goes out of the window. Relay classic and Ramda are examples of this.
  • Some popular functional libraries are useless with Flow e.g. Ramda.js, we love it, but Flow has no clue what is happening there. Definitions for Ramda don’t work well.
  • Learning the Flow type system is more complex than learning the Elm one
  • Gradual typing is not a great thing in my opinion, because you start adding types in one side of the app, then another side of the app, but when finally you meet in the middle the types don’t match, and is a nightmare to fix all the mismatchs.
  • At times we had to write JS in convoluted ways just so Flow could type check something
  • Our code was littered with invariants (assert that something is what is supposed to be or throw an error), because Flow is just lacking
  • I was scared all the time to make big refactors with Flow

Elm is an entire different ball game when it comes to type safety and refactoring.


I think it still is the differentiator in that situation, because Elm’s type system is much stronger.

A few points on dependencies:

Comparing Elm Package manager vs NPM
You can be a lot more confident that the code does not do anything nasty in the background.
And semantic versioning of dependencies.

Since Elm does not have packages for everything, you use less time on making decisions, more time to code.
Also since there is many missing packages, you are forced to think about creating a function yourself instead of just downloading yet another dependency…
An example: I needed Oauth2 Implicit Login to access an API (Open ID).
Why would you download a dependency when all you do is make a link to an external login-site on a normal html-button. And then parse the token in url when redirected back…
If in Javascript land, you would probably not think at all and just download a dependency, instead of using 5 min coding and not adding anything to your bundle.


Can you expand on this? Can libraries not make network requests? Does the Elm package manager pull directly from an open source repo?

Both of these points are things I hadn’t thought of yet and would probably be the most compelling reasons I’ve found for our team.

Any library that you use as helper logic around your app cannot do side-effects at all. The only libraries that can do sideeffects is the one that you trigger in update yourself “(model, sideeffects)”
Typically like the HTTP package.

Compare that to javascript/typescript where any of the million functions deep down in your dependencies can do whatever it wants, whenever it wants.

I guess Elms package manager has its own version of the package… Because I dont belive it is possible to remove a published package… Even if you delete your github repo, Its still available in Elm… Not 100% sure about this one, but can remember people that wanted to remove some packages a while ago.

1 Like

Oh, what I meant here is that NPM allows publishing any random chunk of code, whether it’s in a repo or not. But it looks like Elm simply lets you publish a repo as a package and it pulls its copy of the package directly from that repo, rather than from some arbitrary source you have locally. Is that right?

What did you use to run elm on iOS and Android?

Is that person technical or not? Could there be hidden causes, e.g. HR have a hard time finding developers, maybe because they are looking for Elm developers specifically instead of just looking for skilled people who are curious enought to learn a new language?


Network requests have to be accomplished by sending a Cmd to the Elm run-time, so any library that wants to send data to an external party has to go through you. That makes it easy to at least inspect the code that is producing the Cmd and check that it isn’t sending something malicious out.

The only exception to this is that a library can also produce HTML that can have side effects when rendered, but that is still pretty easy to inspect. You can see more here.


@sebn good question! The person who is sceptical of Elm is very much non-technical. I agree that searching for curious/creative people is a much better way of finding someone that will go beyond simply copy-pasting a superficial fix to the current problem.


The decision maker may have used some JQuery or installed a Wordpress Plugin but have not hand-crafted any meaningful application logic from scratch or felt the pain of maintaining something with “moving target” dependencies. Sadly, without writing any Elm code, a non-technical decision maker is unlikely to see the benefits of type-safety and refactoring confidence and friendly compiler warnings which is where Elm shines compared to other options! Furthermore if the person is only focussed on delivering the current feature set as quickly as possible, and not concerned with long-term maintenance (because they won’t have to personally maintain whatever code is written), they tend to default to “ready made” over carefully crafted solutions. :hamburger: vs. :green_salad:

We intend to cover the availability of people with existing Elm skills in the post we’re writing, and demonstrate that there are many more people available who are both capable and want to use Elm than a basic keyword search on a CV/recruitment site reveals.
The trick to finding great people is having an interesting job description, flexible working conditions (e.g: remote work) and great company culture that invites people to apply. :sunny:
Sadly, most companies don’t put in the effort in any of these areas and instead want to simply hire someone for the “job to be done” with the same convenience someone with the munchies going to the corner store to buy a pack of chips. :roll_eyes:

As you say, HR only have a “hard time” finding people if they are focussed on finding the Elm keyword on a person’s CV or LinkedIn profile. Anyone hiring someone to do a technical job should focus on one thing: evidence of proactive learning. :books:

Paul Graham described this eloquently in 2004 when comparing the search for Python (a comparatively “new” language at the time) vs. Java (established industry-leader) programmers:

…you could get smarter programmers to work on a Python project than you could to work on a Java project.
It’s a lot of work to learn a new programming language. And people don’t learn Python because it will get them a job; they learn it because they genuinely like to program and aren’t satisfied with the languages they already know.
The Python Paradox: :eyes:

At the time Java was taught in universities whereas Python was not. So the people who learned Python did so out of curiosity to try something new. :rainbow:

Essentially, hire people who are conscientious about learning new skills.
The chances that someone already knows how to do everything in a given app are low (unless it’s a cookie-cutter Wordpress website, Shopify store or similarly straightforward project where everything is a “solved problem” that requires limited thought…). The person’s ability to learn fast and not be overwhelmed by new challenges is far more important than existing knowledge. :bulb:

One of the advantages of GitHub is that it’s easy to see if the person has a genuine curiosity for learning Elm (they have a personal project that uses it and have “starred” a few Elm repos/examples) this is a good “filter”.
e.g: :mag:

If there are a million people with coal mining skills (or something equally irrelevant to the problem you are trying to solve) what does it matter if what you need is one person with electric car battery management experience? If a decision maker uses an availability bias or have an incomplete understanding of the problem’s lifecycle to make technology decisions, they will end up hiring the wrong person to produce the wrong result. :slightly_frowning_face:

Not saying that Elm is always the “right” choice for all web projects.
Just that in many front-end heavy web apps, it’s by far the wisest choice for both short-term delivery and long-term sustainability of the project! Decision makers who embrace Elm see huge benefits both in terms of the quality product they are building and the high calibre people they can attract to work on it. :blush:

We need to get more evidence of this so we aren’t asking anyone to have “faith”. :thought_balloon:


We switched to Elm a few years back and have never looked back. I suppose it was easier from my perspective because I was the decision maker, but I still had to get buy in from all the devs… Most of whom were react / non FP devs. I held lunch and learns to show the benefits, then we slowly started using it wherever we could… Very small areas initially. The hiring argument has never been a problem. I’ve never hired anyone who knew Elm already, but I also haven’t experienced anyone having a difficult time ramping up on it in a very short time. Also in every case, they we’re eager to come on board with the prospect of getting to use it.
Not to throw shade, but something seems amiss to me that a non technical leader is determining what the stack should be. A good leader should instead hire people that they trust, and trust them to make those kind of decisions IMO.


I can share a bit of our experience. I would like to share more someday and hope I can find time for that.
In our team, we switched to Elm around a year ago. The interesting fact is that we are hiring front-end developers for a long time already. And when AngularJS position was opened lonely we hired no one. Since we are hiring Elm devs we already hired two new employees who are desired to work with Elm. Which is a great thing for managers. They can see the result in practice. Because code change from AngularJS to Elm has no visual difference (maybe rendering is faster in Elm version). It’s still the same looking app, which inside is much more reliable.


Another interesting fact is that we found a great solution to reuse existing code in Elm. Which makes the transition painless. We write all the new stuff in Elm. We reuse old AngularJS code from Elm. When it’s time to do a major refactoring of old AngularJS code we rewrite some parts to Elm. So the transition is very smooth.


Thanks for the link! Exactly what I was looking for. :+1:


Could you say more about how you reuse AngularJS components from Elm? My project currently has a big AngularJS app, and if there’s any chance we’re going to move away from that, we should be able to reuse some existing code in Elm at least

1 Like

I wrote about it here. Please let me know if you have questions. We may create an NPM package if it will be useful.


This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.