This post is split in two parts, one written in 2022, which is a report I wrote as I was writing my first ever ELM lines. The second part, written in 2025, completes it with my experience on a production project.
Original - 2022
Introduction
The goal of this post is to give you my thoughts while experimenting for the first time with the ELM programming language.
Before this, I would like to thank Ben from Biggest Lab who introduced me to this language. They have been using ELM in production for a while and he has been a big help and motivator for this article.
Understanding ELM
ELM is a functional domain specific language mainly for creating web front ends. Hence, it transpiles to JavaScript and is kind of competing against frameworks like of React or Vue.
A simple counter example :
-- imports/exports omitted
main =
Browser.sandbox { init = init, update = update, view = view }
-- MODEL
type alias Model = Int
init : Model
init =
0
-- UPDATE
type Msg
= Increment
| Decrement
update : Msg -> Model -> Model
update msg model =
case msg of
Increment ->
model + 1
Decrement ->
model - 1
-- VIEW
view : Model -> Html Msg
view model =
div []
[ button [ onClick Decrement ] [ text "-" ]
, div [] [ text (String.fromInt model) ]
, button [ onClick Increment ] [ text "+" ]
]
Check it out in the official ELM sandbox
Now before starting anything, I wanted to get a grasp of the strengths and weaknesses of the language, so I compiled the following list. It is based on the comparison of other JS frameworks on the official website and the complaints people had most often on forums.
Promises
- No runtime exceptions
- Easier refactoring
- Better error messages
- Performances
- Enforced semver - this was something I was not expecting but I find very nice 👌
- Small size
- Javascript interop
Complaints
- Debuging is a pain - this is true for most functional languages as far as I know
- Documentation is incomplete
- 0.19 broke a lot of things - it was released in 2019
- Leadership of the project seems dubious - Why I’m leaving ELM
- Fine grained DOM control is a pain
- Performance regressions on some specific tasks
Is it dead ?
At time of writing, the compiler code seems to be hosted on Github under the ELM organisation. One thing is clear - the repository is not active enough to reassure me : the last commit was 14 months ago and there is 200+ open issues and 25 active pull requests. That’s not looking good, and going through the internet you can see a lot of people asking if the language is dead.
However, the ELM twitter (now X) account retweets content daily, there are meetups about ELM and people seem to use it for production projects. The ELM Weekly newsletter is also going strong, posting weekly as its name implies. Reddit and discourse see some activity to.
So at this point I was asking myself: is it dead or not ?
From my understanding, in 2021 the creator of ELM, Evan Czaplicki, said he was still working on some features but that it will stay a very stable language for the foreseable future. I am on board with this way of thinking, hence I decided to keep going.
Installation
Installation was a good experience. It was surprisingly not in fedora’s nor in most distributions package repositories (repology). You can just curl the compressed binary.
Learning the syntax
I learnt the basics the way I usually do with new languages : exercism.org! They have an entire ELM syllabus I decided was a good way to get started.
First impression : coming from Haskell, the syntax and the descriptive nature of functional programing was familiar. If coming from a imperative only background, this can however be a learning curve. But the comments, functions, exports, imports, typing look very similar if not exactly the same. I can see Evan liked Haskell very much !
I was surprised that that the two tools suggested by exercism : elm-test and elm-format were installable through npm and not through some elm package format. This was just a remark and not really a problem though.
A few frustrations I have had, in no particular order:
- No function level pattern matching - Can do without
- No guards - Much cleaner than if / else blocks in my opinion
- Reversed : (cons) with :: (type) compared to Haskell
- I miss the ($) operator from haskell
- Missing the type classes
- I miss the where closes
- On some occasions the compiler printed pages of empty characters
On the other side:
- Repl experience was nice
- The compiler writing at the first person is very funny at first and makes the errors clearer. I wish more compilers did that.
- Destructuring seems to work nicely
The final boss for me was the inability to match two times the same record. This made me stuck on one problem and will hopefully change in a future update.
Final test
At this point I discovered Haskell Miso and was getting ready to shift my focus. However, Ben made me realise that I was looking at ELM the wrong way. I was studying as if it was a generalist language, but it is a domain specific language, it was made for a specific task : building frontends. So I gave up on Exercism and decided to do a little project.
I first started with the official tutorial. After playing a little with it I could already say with confidence that I like this way of doing better than React. In my opinion ELM being a DSL gives it an edge compared to react (a JavaScript library). The whole language, syntax and tools were made for this task and it shows.
I kept going and made a simple weather application (GitHub) based on the OpenWeather API. Only issue I faced was making elm-geolocation work the way I wanted. I ended up just adding inputs for longitude and latitude.
Working on a production ELM project
You might have noticed the previous part ended a bit abruptly ! I did not know how to finish the article and ended up getting distracted in Thailand 😅
I am now employed at Nomalab, a Media service company. I would not have thought that I would code something again with this language, that already appeared dead~ish to me 3 years ago. But here I am, experiencing a big code base in ELM.
Only complaint so far is that I feel like I spend my time jumping between 10 different files, only to immediately forget where I come from. This might be caused by bad initial architecture. Or because past employees at Nomalab had some kind of ELM backend initially (now replaced by a mix of Scala and TypeScript).
Anyways, ELM is getting replaced here by React. Slowly.
Conclusion
ELM is one of the best development experience I have had so far and I would use without hesitation over React or Vue for personal projects and POCs. It does one thing and does it well.
Unfortunately, it stayed a niche frontend tool. My best guess is that it was easier / more cost effective to hire JavaScript people than to hire and train on ELM. And if I were a CTO right now, why would I use ELM when most people are familiar with React out of university ?
I have been told by friends of new tools like Gleam or PureScript that are being actively developed and have a similar spirit. However, I don’t feel like investing in learning those just yet.
After 3 years of postponing I am somewhat proud of finally getting this article out. I think this kind of content where I dive into something for a day or a weekend is much more productive than logging every month and I intend to make more.
Thank you for reading !