Reasons that people were forced to move from Elm to something else?

By “express” I meant “express in specific style”. Of course it’s still a complete language and I should not use word “cannot” - you of course can, but you need to sacrifice style.

But to be specific - I find Elm lacking with handling polymorphism. For example we’d like to have structures with functions that operate on them, but elements of these structures should be polymorphic.

Typeclasses and/or Modules also provide tools for late polymorphism, where you can define some type behaviour later.

We also model a lot of flows in our apps (think about document flow in organisation) and GADTs are very useful for this.

I didn’t compare TS and Elm in this regard. We use TS for our UI and if somebody wants to still work with javascript libs or idioms, TS is unmatched here. TS tries to be subset of javascript and obey by its laws and best practices. Elm and TS are different tools with different goals.


I am curious about this, if Elm did not fit your needs here, what did you use instead that did?

Also, what is the domain we are talking about here?

1 Like

Our recommendation in the team is Reason right now. We also used and allow Purescript for new projects.

Our domain is mostly legal/compliance flows. Think about legal entities and documents in multiple versions and multiple version of schemas and our app transforms it between them - one employee publishes document that should be compliant with one regulation, then another changes it to make it compliant with another schema and make it pending for review in different department …

1 Like

I get that Purescript is Haskell so has a more powerful type system than Elm. Its been a while since I used OCaml (20 years), what does Reason have modelling wise over Elm? Is the extensible union types? Or the module system perhaps?


GADTs and polymorphic variants open a lot of possibilities for us. Also module system is more powerful (really, modules are different thing in OCaml and name is rather poor).

We use GADTs to express flows as data structures and interpreters for them.

Module system helps with parsers and writing isomorphisms for schemas (functions that convert between complex data structures) - we can extend more basic types with implementations so bigger isos/parsers compose better.

Polymorphic variants are mote like a nice tool here and there - they change nothing in big way, but are quite useful for pseudo row types. This is more like stylistic choice and to be honest, we find Elm extensible records good fit for the same use cases.

Also, please note that our recommendations are taking into consideration multiple factors. We chose Reason not only because of “more powerful” type system but also due to genType, interoperability, community and tooling. It is just a result of specific needs.


I posted in that slack thread. I’ll post here too.

A while back, I joined a company who’s plan was that everything new was going to be Elm, and my team was beginning an important new Elm project for the company. The company had three teams of 6 developers, and each team had 3 frontend devs. Eventually, by time 50% of the front end code was in Elm, the company made the decision that Elm was cancelled, and nothing new would be made in Elm. It was around that time that I quit, which coincided with a lot of other people quitting (for various reasons not related to Elm).

During my time there, I took an Elm project from nothing to completion in about 7 months. And I am very happy to say it is still maintained and in production! Thousands of people are still using it every day. Even though the company gave up on Elm, it seems Elm did not give up on the company :tada: .

Here are some details about the company dropping Elm.

A lot of our Elm developers didnt want to be Elm developers in the first place.

I joined the company to write Elm. A few others were really excited about Elm. But many didnt even know what Elm was when they were told their projects were to be written in Elm. Developers reacted in different ways. One quit, thinking that Elm was a big waste of time in his career. Lots of developers tried it out with at least some hating it, but most being ambivalent. I think “Its nice, but I am faster in React” was a common conclusion among those who were indifferent. The breakdown was roughly 35% Elm-lovers, 50% neutral, 15% Elm-haters.

Lesson Learned

These kinds of technical decisions need to be made “ground-up”. The odds that any random programmer is going to be excited about Elm after learning about it are low (which is the case for any technology) and programmers are more affected by these technical decisions than anyone else- even customers. So programmers are the stakeholder that is the most relevant to these decisions. If you want to become an “Elm company” you first need a lot of developers and teams who are interested in Elm. If you dont have that first step out of the way then you really just cant become an “Elm Company” without making a huge gamble that many people wont share your enthusiasm and thereafter dislike their job. Elm is not so amazingly good that you can just count on everyone loving it when they get exposed to it.

I was not allowed to help Elm newcomers

Since we had a lot of people who didnt know Elm very well, and I often felt like “the Elm guy”. I spent a lot of time reviewing PRs and coming over to people’s desks to help them out. At some point, management made a judgement that teams were not closely integrated enough. They felt that there was too much communication between frontend people on different teams, and not enough communication between frontend and backend people on the same team. Therefore, people like me were supposed to stop helping frontend people on different teams as I was.

The consequence of this, I think, was there there were some teams that had no Elm expertise, only mild Elm enthusiasm, and no in-house Elm support; and they were nonetheless supposed to be writing projects in Elm. Not very promising conditions.

Lesson Learned

Within companies, there develop natural communication networks. Some coworkers communicate with each other every day, others never communicate. My company reasoned “we need communication to follow the existing teams, therefore, we will mandate that that exact communication pattern”, but it really doesnt work like that. I think how people self-organize is a little bit more like an immutable law of the universe and less like a thing that can be dictated into existence. In practice, people communicate with who they need to communicate with; issues with shyness or confrontation aside. Management is also not omniscient; they dont fully understand the communication patterns inside their company. Therefore, management should be a little bit “laissez-faire” about teams: observe who communicates with who, and then draw team-boundaries around those natural communication clusters.

Elm arguments got really really tiresome

The road of project development is bumpy, and Elm was a younger language back then with more open questions about how this or that problem should be solved. In our company, there were always at least a few people who really didnt like Elm, and whenever we hit a snag, there was always someone to say something like “In React this is just…”, spawning a new discussion about whether Elm was fundamentally good or bad. I love these discussions and arguments recreationally in my own time, but on the job its a real drag. Development stops when fundamental arguments about technology are opened up. It got worse and worse over time. Difficulties with upgrading to the then-upcoming 0.19 release added fuel on that fire. Our CTO “switched sides” and lost his love for Elm, and kind of became an agitator himself in these arguments. I remember feeling like “I wish I could have spent this time solving the problem, rather than defending Elm in an argument. I could have just solved the problem, regardless to if they are ultimately right that its easier in React”.

Lesson Learned

You really should keep your eye on the prize at work: getting projects done. Your company has to pick which technology to use, and you have some choice in what kinds of companies you want to work at, but outside of that, if you just wanted to get projects done, why would you be wondering which technology to pick?

I have adopted a few morals about how to get past tech disagreements. One is “code is worth a thousand words”. If you have a tech disagreement, one or both sides of the disagreement should go off for a day and write up the best demonstration of their opinion so everyone can see it shine. Another is “let people be wrong”; just letting an opinion play out naturally is often the most cost-efficient way of getting better opinions. Putting an opinion into practice creates the best evidence that that opinion is good and the quality of this evidence is often so good that it is worth the risk of having to refactor or re-do the code later. If you trust your coworkers, you should expect them to learn from good quality evidence in a positive direction.


Would you say that there were genuine technical problems in Elm that made developing this project difficult? Or would you say that any problems you hit were solvable in Elm quite easily?

1 Like

Wow, thanks Chad for this write up. I think your summary is very accurate.
(Clarification: I used to work with Chad, at that company. Matter of fact, I was the one who hired him.)

Chad outlined things so greatly that I don’t even have much to add to the points he mentioned so well, but I can give a bit of my perspective on the matter:

The two years I was there for were marked by huge changes. Organizationally, staff-wise, technology and product-wise, and also strategically. I have never seen more people come and go in such a short period of time as at that company then.

Trying to create some stability for the frontend team in an environment when everything changed daily, we took the opportunity to write lots of Elm code in our newly created microfrontend architecture. To me the most important thing was teaching people Elm, which had varying levels of acceptance.

There were no solid arguments against Elm. They all pretty much boiled down to “I prefer React because I already know it” in various disguises and that is ok. Not everyone will agree on this. However, there was nothing technical in the Elm projects that would’ve forced anyone to not use Elm. In fact Elm was great for stability, asset size and (if people had learned enough) development speed.

However, like Chad said, high acceptance for Elm and helping others learn would have been hugely important. It sounds strange when you read “I was not allowed to help others” but there were forces in that companies that were very political and I would there was quite some back-stabbing behavior going on. In hindsight I should’ve been more outspoken against those forces, but at the time I was honestly not 100% clear on the depth of those actions.

Anyway, I agree with Chad that everything stands and falls with having people that are interested in Elm. Unfortunately, the people who are not often have reasons that tends to convice management more (React is stable, backed by Facebook, enterprise, yadadad) :slight_smile:


Hey thanks for the reply. Yeah I noticed in my original message I didnt go into any of that. I do mostly feel like Elm wasnt presenting any technical barriers to our development. I dont want to be unfair to the folks at the company who didnt like Elm, who probably did feel that Elm presented blocking technical problems. So let me try and list out some tense technical topics that maybe approximate what the other side felt was a blocking technical problem.

Api Tokens

Our Elm projects used a lot of ports for http requests. This is because our company already had a strong frontend JS api project that was re-used everywhere for these kinds of requests. One day we tried to do all the http for an Elm project wtihin Elm, just to see how it would go. We quickly ran into problems with how to store and refresh an api token in the Elm model. No one had a really good idea on how to do that in our existing set up. I remember that being an embarrassing day for the pro-Elm side of the discussion because others felt it should be trivial.

This is a non-problem for me now, simply because I now know how to do this well in Elm. We really were on the bleeding edge of Elm development, and I dont think good examples even existed online. I think the competing JS implementation for how to do the API token stuff relied on mutable JS objects, which, I guess would indeed make the problem a breeze, at a big sacrifice to our stability. I remember some of us were looking towards Haskell for inspiration, and I think the leading example relied on typeclasses and very effect-ful and IO heavy operations.

Reusable view components

At least in my project, I feel like we suffered a lot of “similar is different than same” problems regarding our UI components. Two spots in the UI would look very similar but had subtle differences, that would tempt me to make a re-usable component. But, the subtle differences masked the code complexity involved in making one common reusable component, and that complexity was great enough to undermine the point of reusable components altogether. So, personally my solution was writing a lot of duplicate code manually. The amount of duplicate code I was writing might not have impressed the Elm-skeptics in the company.

Just like the previous point, this just is not a problem for me anymore. It took time, but I and seemingly the Elm community as a whole gradually learned good ways of making code re-usable in Elm. In some ways this is not even an Elm specific problem. The way I think about reusability now is not an Elm specific domain. Its just a nut you have to crack in every language and I could have gotten it wrong in React too.

0.19 Navigation

As the 0.19 release approached, I think we knew the api for url navigation in 0.19 was quite strict, and that in 0.19 you could only do url navigation if your Elm app had control over the whole page. Well, guess what! We had a lot of small Elm widgets that did navigation, so in order to migrate we would probably have to come up with our own solution that involved a lot of ports. I recall someone saying “Evan thinks we are stupid” in reflection on this, as in, Evan wrote an api to force us to take a certain approach, which implies he doesnt think we can make this choice ourselves.

It seems like the Elm-skeptics had a point, that Evan did in fact add difficulty to our ability to upgrade. Whether or not this additional difficulty on our end was justified in the grand scheme of things, or whether or not it was a good design to begin with, are two questions I just dont know the answer to. But, either way, the whole topic was not relevant in any practical way: we were not at the moment trying to upgrade to 0.19; we didnt necessarily even need to upgrade to 0.19, 0.18 was doing great; and the upgrade path we did have to 0.19 was not in fact overwhelmingly difficult. So, in my view, which sides of the discussion were right had little relevance to writing Elm code; but it was probably taken as a sign that Elm is going to create big problems for us anyway.


Totally with Chad again on this.

While I do believe Elm solved a lot more technical problems than it presented compared to alternatives such as React, I do think Elm comes with its share of organizational, communication problems. I believe is a thing that makes Elm really hard to sell to even open-minded sceptics:

That thing is: Why are there issues and PRs open for years that involve bug fixes? I think they should be closed or worked on. I don’t mind not getting new features but I do think releasing bug fixes in an appropriate amount of time is critical for credibility.

I love Elm and have taught Elm to at least ten people, but this one is really hard to defend IMO.


I come back to Elm every so often just to see if it’s still around. I see the last release was a year ago now, and that brings me to the issue I had convincing my co-worker to look at it. How do you convince someone to seriously consider a project that is not at 1.00 at least and seems to be moribund release wise? I realize that neither of these are the case but to the outsider it sure seems like it.


Eh, why would you release a new version of the compiler if the old one is still working fine? Much of the action is in the libraries.

It’s a communication issue: the version number implies that the language is not stable (or it would be at 1.x), so people expect things to be changing. But since there doesn’t appear to be a lot of change going on (either in the form of releases or blog posts), it’s easy to assume that the language must be stagnating. You can explain how things work in Elm land of course, but first impressions are still important.


This doesn’t mean anything. React Native is 0.63 and is production ready for years, lots and lots of companies use in production. And having less releases is a desirable thing, the correct name is stability, big companies need it. Evan still works full time on the project.


Long-open bugfix PRs are another reason for this perception


React Native is 0.63 and is production ready for years

That’s definitely an outlier / exception to the rule … First of all, React Native is developed, financially backed, promoted and heavily used by massive companies. Secondly, there’s the great branding associated with React that React Native piggy backs on. Sure, React Native is not yet in 1.0, but React is and has been for a long time.

Follow-up / edit: My point is, by having a 0.x.y version, you’re already raising eyebrows for folks who may not be fully aware of the language / library / ecosystem. So it’s already an up-hill battle at that point.


why would you release a new version of the compiler if the old one is still working fine? Much of the action is in the libraries.

Perhaps for optics. To help sway management and ease concern of skeptical colleagues. And to signal to people that “this compiler is indeed quite stable and has been used in production by several folks”.


React was already widely adopted on version 0.14. Then, they decided to strip the 0 and the next version became 15, but in fact it should have been 0.15, and the current one should be 0.17. Or maybe it should have been called 1.0.0, but being on 1.0.0 also feels immature, so they skipped 14 numbers. Browsers used to release new major versions every few years. Then, chrome decided that everything should be a major version. Now, i f you are in version 1.0.0 you look in early stages compared to chrome. Instead of playing around numbers, check the ecosystem. JavaScript has been there since last century and still has a messy ecosystem pushed forward by hypes that last after a few months.

Also, nowadays, with continuous integration, it is common to promote releases, not create new ones. So 1.2.0-alpha becomes 1.2.0-beta and, afterwards, 1.2.0-stable, but they are exactly the same thing only with different tagging.

So, Chrome could be at version 3.7, React could be at version 1.2, and Elm could be 2.1. The number is irrelevant, the important thing is what they offer.

1 Like

Could you elaborate on that? What is the main advantage of React here? One of the more obvious advantages of Elm seems to be the ability to create reusable elements with extreme flexibility. Is the problem that you need to use and and hook up everything to the app’s main update function?


I’m not saying React is better for UI, in fact I am convinced Elm’s guarantees are much more desirable than the alternatives.

What I wanted to say though was that:

  • React is very easy to grasp mentally and sell to a team of developers, because a “component” is a seemingly simple concept and every component has the same, simple pattern. It’s easy to understand and get right into it. Of course in the long-term local state is something you end up wanting to avoid. But the point stands.
  • It is difficult in Elm to know the right pattern for something in the UI. There are many questions one has to deal with. Should we try to emulate Evan’s SortableTable or should it just be a view function? or should it be a collection of functions and a model and update? And even if you sort out a good pattern it doesn’t mean it applies to the next piece of UI, every new “chunk” of UI is something of its own, and it most likely differs from app to app. After all this, then one has to care for, as you say, hook everything up (as opposed to just one line in React).

I know the reasons for why this is the case, and am sure React hides a lot of the complexity at the cost of many other issues which will eventually show up. I am confident Elm is a much more solid option for modelling UI.

But as a matter of “why people move away from Elm” I think the Elm community should not underestimate how seemingly unnecessarily complex Elm appears as opposed to React components and one-line examples. So many times did I encounter rolling eyes and “why does it need to be this complicated? in react it’s just …”.

Also, even if one has an optimistic attitude towards learning Elm it is discouraging to find little help in learning how to think about UI “chunks” (to avoid the dreaded “component” term). Maybe UI chunks should not even be a special thing in Elm, but it is obvious that most people coming from JS still ask the question.

I think a series of something like elm patterns or elm css patterns for different common patterns for structuring UI “chunks” would go a long way. If nothing else, we should help convinced elm developers to communicate what would a UI library look in Elm.

UPDATE: should leave this great resource here as well