Elm and why it’s not quite ready yet

Will Elm ever be ready?

Chris Gregori
Bits and Pieces

--

Photo by Jorge Franco (Unsplash)

Who knows — probably? That’s not the point of this article – I am not going to talk about what Elm could be, I am going to tell you what it is today.

Disclaimer: This article is comprised of my views alone, not my employers, colleagues or publications.

What is Elm?

Elm is a functional language that compiles to JavaScript — think of it as a competitor to React or Vue, and is used to create websites and web apps.

Elm promises no run time exceptions — no null and no undefined is not a function. It uses type inference to detect corner cases and help the user with what the issue might be.

One of the biggest features is that Elm also comes built with a robust type system and a compiler to help you during development. No need for TypeScript — these are actual types that the code must adhere to.

It’s no slouch when it comes to performance either — comparing it to React and Vue it seems to produce slightly-smaller bundle sizes and faster render times. These metrics weren’t gathered by me but I trust the source. Elm doesn’t feel slow by any means.

Tip: Share and sync components across apps to build faster. Use tools like Bit (GitHub) to share your existing components as a reusable collection. Try it.

Components with Bit: Easily share, reuse and sync across projects

Why have I been using Elm?

At my workplace we use Elixir, a functional language you might’ve heard of which is built on BEAM (the Erlang VM) and has been picking up a fair amount of traction lately— many tech teams (Ruby shops in particular) are starting to adopt it due to its elegant syntax, powerful functional features and it’s natural talent for highly concurrent, real-time systems. I won’t go into the beauty of Elixir here but it’s quickly becoming one of my favourite languages to code in. If you’d like to hear more, take a look at this blog post by Discord or read about how other companies are utilising BEAM to great effect.

Due to its functional nature, Elm felt right at home to many developers on my team due to their background and fondness for functional programming (and hatred of OO). It’s a niche language still in a state of infancy (v0.19) so we were aware there may be some teething issues we’d have to deal with. The team felt these potential problems were worth the out-of-the-box features Elm provided such as the type system and one-way data flow model. We were already using Elixir which is fairly niche so why not go all in on the bleeding edge tech stack?

We’re currently using Elm (in production) to build some dynamic front-end features to our admin pages and in our new employer job application submission app.

The good

Let’s get this clear first, working in Elm hasn’t been all bad. Here are some of my brief highlights:

  • Refactoring is a breeze due to the strict typing and compiled aspect
  • The compiler is very helpful to work with most of the time and helps point you in the right direction for the most part
  • Immutability and Uni-directional data flow is baked right in — think Redux
  • Functional design and currying make functional composition very nice to work with
  • Styling system based on modern CSS in JS approaches (see Styled-Components)
  • You mostly don’t need to write front end tests!

The bad

But Elm isn’t all roses. It seems great on paper but I’ve found developing a real, production system with it has issues. Here are the biggest pain points from my brief time with Elm to date:

Debugging looks awful and is largely unhelpful

Elm has a version of console.log — you can use a debug statement to print whatever you want out but not without writing perfect code. Elm doesn’t allow you to have side effects meaning you can’t write code which doesn’t return or is used in the main execution path. So okay I can stick a Debug.log in front of the code which updates my model right? There’s no way to pretty print it so it’ll look something like this:

: (Show { apprenticeshipQualification = Just “6”, qualifications = [{ id = 1, name = “Project Manager — Level 3” },{ id = 5, name = “IT User Skills — Level 3” },{ id = 4, name = “Digital Marketer — Level 3” },{ id = 1, name = “Assistant Accountant — Level 3” },{ id = 2, name = “Customer Service Practitioner — Level 2” },{ id = 8, name = “Software Developer — Level 4” }], basicsErrors = [], companyId = 1, date = Nothing, datePicker = DatePicker { focused = Just (RD 737201), forceOpen = False, inputText = Nothing, open = False, today = RD 737201 }, duration = “18”, goodCandidateErrors = [], goodCandidateRequirements = “• ", hiringManagers = [{ employeeId = 1, firstName = “Dorian”, lastName = “Bahringer” },{ employeeId = 2, firstName = “Felipe”, lastName = “Jacobi” }], hiringProcessErrors = [], salary = “18000”, selectedHiringManagers = Dict.fromList [], shortIntroductionErrors = [], trainingProvider = Just “Company A”, typicalDayErrors = [], url = { fragment = Nothing, host = “localhost”, path = “/app/basics”, port_ = Just 4001, protocol = Http, query = Nothing } },<internals>)

There is an Elm debugger (imagine Redux devtools) but that doesn’t work for our app so we can’t use it — using certain message types (think of Redux actions if you’re from React-land) cause the debugger to throw up.

You cannot install Elm packages from anywhere other than the official package repository.

Imagine you have a package that you want to use but it requires a PR to improve, slightly tweak, or fix the functionality. Say the maintainer isn’t replying and won’t merge in any outstanding pull requests. With Elm you’re unable to fork and host your own version in Github without also publishing an entirely new package on package.elm-lang.org .

Most of the tutorials / examples online are out of date due to v0.19

In the last month of writing Elm, I’ve been unable to find clear, concise answers to seemingly simple questions or follow along with any clear examples due to them all being out of date. This can happen with any language yes, and it’s currently the case with Elm.

The docs are incomplete

Again, this is fine and to be expected given that it’s a new language and not at v1 yet but that harkens back to my original point that it’s not ready yet. A new application we’ve recently built at my company with Elm had a requirement for a single-page-application with routing.

I followed along the official docs for implementing client side routing, started adding things that made sense in the app until I found this:

Great.

Elm core development lives in a walled garden that you can’t touch, even if you wanted to

Starting from v0.19, no one except those with access to elm-lang or elm-explorations Github account can write native code — not even for private use, not even for “explorations” (unless Evan — the creator — gives you a repo). If you have native code and want to upgrade, you’ll have to fork the compiler and remove this restriction.

Photo by Jason Blackeye (Unsplash)

See for yourself — it’s baked right into the language source code.

This has lead to a vast amount of the community wondering if Elm is going to flourish or fumble. Whilst I personally haven’t had any direct issue with this yet, I don’t agree with it as fundamental principle of how a language is built and consumed.

Taken directly from a reddit post discussing the if users should continue to use Elm:

No, it’s not worth it. I prefer a language whose design approach isn’t rooted in an inherent distrust of its users.

Pull requests being open for 2+ years

Runtime errors can happen

This one shocked me and I had to check it through a few times. Whilst working on a feature I discovered that Elm (despite its promises) can have runtime errors.

I was handling a click event when selecting a checkbox and expecting a tuple to be sent to the model. It compiled with no errors, it ran the app but when I clicked the box, it gave me a big ol’ undecipherable JavaScript runtime error. I felt like I had just been lied to.

Missing key features

At the time of writing, Elm has no implementation for server side rendering, web sockets or localStorage.

Lacks the ecosystem of its siblings

A major point that cannot be overstated — using tried and tested front end systems like React or Vue mean you get access to an extremely large library of high quality packages, tools and community support.

I won’t go into mass detail here (and this is largely down to adoption and the time they’ve been around) but if you want to see more, checkout some of the things you can do with minimal implementation thanks to the scores of open-source developers:

And compare them to Elms equivalent:

The biggest problem

What is one of the most core things that developers, tech shops, and entrepreneurs are looking to do to help stand out from the crowd or even survive? Iterate quickly.

Can Elm help you do this? Yes it can! Once you’ve established the types in your application and have some basic app scaffolding it can be quite fast to iterate on features. The one-way data flow is great (so great that Redux was inspired by it), the compiler can help you debug and refactor with relative ease and the type system can be quite expressive. But in my opinion it can only accelerate you to a steep plateau before things start to slow down.

What if you want a service worker in your app for offline support? What if you want localStorage? Server Side Rendering? What if you want transparency in what’s going on with the future of the language you’re using?

A small extract from enaqx/awesome-react on Github

Yes, Elm can do quite a bit and it can do it quite well, but it’s current inability to provide stable documentation for key features, its lack of developer transparency, and lack of (in my opinion) fundamental features like SSR means it’s not ready when you could use something battle-tested like Vue or React which come with everything you could want and more. The other options (which yes, you likely have to write tests for) have the backing of a solid ecosystem which helps tackle the issues you’ll actually come across during day-to-day work, meaning that ultimately, you will be iterating faster.

Conclusion

You can use Elm. It’ll work for the most part and it might avoid some of the headaches you may get with other front-end solutions, but you’ll be giving up a smorgasbord of fantastic open-source ready-to-use packages, key features like Server Side Rendering (yes I know GoogleBot now parses JS), thousands of tutorials, a large, thriving, passionate community, and complete and robust documentation. Yes, you may have to write some tests (but you should really be writing business logic tests anyway!).

I’m not saying that people shouldn’t adopt new technologies; I love playing with new languages and paradigms, Elm’s been quite interesting to get to know — but contrary to the promises, I don’t think it is currently the fastest or safest option, and sometimes that’s what matters most.

--

--

Senior Software Engineer @Multiverse — ex @Skyscanner & @NETAPORTER