Elm is a ML-style functional language with enforced immutability that compiles down to optimized JavaScript. It solves a lot of problems that developers writing JavaScript end up facing in a day-to-day workflow. I believe that it is going to be the future of front end development. I’ll be going over a few aspects of Elm that I think make it so powerful.

“JavaScript Fatigue”

I think that one of the biggest reasons to use Elm is to avoid trying to put together all the different libraries and tools to get a scalable JavaScript project going. There are constantly new libraries being released. I think that’s great and it shows that the ecosystem is vibrant, but I also believe it makes it hard to keep up with and build larger applications. Elm comes with everything you need to get started building a scalable front end.

Architecture

The concepts around the Elm architecture at its core are starting to be more widely used. For those of you familiar with Redux, it is very similar to that. The Redux project has looked at Elm for inspiration. It is a simple architecture and the documentation does the best job of simplifying it:

The logic of every Elm program will break up into three cleanly separated parts: Model — the state of your application Update — a way to update your state View — a way to view your state as HTML

This architecture is being used by many companies like Prezi, NoRedInk, and CarFax. It allows for complex web applications to scale well and to be refactored easily. The best part is that this is already built-in to the platform. There is no need to setup a bunch of different libraries, you simply install the Elm CLI and start developing.

Compiler

Elm is a statically-typed language with type inference. The compiler is the biggest reason why companies working with Elm gets no run-time exceptions. It acts as a very friendly assistant for you while developing. Rather than going through a use case, let me just show you this:

Elm Error Messages

As you can see from the message above, the compiler is extremely friendly and tells you that your code is missing the case of an empty array as a possible input. Messages like these force you to account for cases that are missed often in developing JavaScript applications which end up throwing some sort of “undefined is not a X” exception. This allows a developer to get very fast feedback on code and helps avoid issues as the application grows. Usually, these kinds of problems are caught during a code review or a test run of the application. Instead, with Elm, you don’t have to worry about forgetting those small cases.

Elm code is translated into efficient JavaScript code. There are constant changes coming to the JavaScript language and browser engines. Rather than having to worry about it and try to refactor your application, you can write your code in Elm and when newer versions of the language are released with compiler updates, you will potentially get more efficient JavaScript code.

I see a big opportunity here with WebAssembly. Having Elm compile to WebAssembly as a target could help significantly improve the performance of an application. Quoting directly from this blog post:

I do not expect to be compiling to JavaScript forever, especially with WebAssembly on the horizon. The smaller the interface between Elm and JS, the easier it will be to support other platforms.

Also — the compiler has even helped developers with ADHD stay focused.

Performance

Elm has always done well with performance due to its compilation to efficient JavaScript and use of the virtual dom model. Many companies currently using Elm have not had to compromise performance for productivity. It just comes built in.

You can see the benchmarks that were run back in July 2014 and more recently in August 2016. They are pretty impressive and I have not read a single account of poor performance from the companies using it in production.

Package System

The package system is one of the most interesting aspects of the Elm ecosystem. It has one feature that isn’t anywhere else (from my knowledge) — it enforces semantic versioning based on the changes to your package. The system can tell if the package is making a breaking change and not allow for the minor version to be bumped and requires the major version bump to publish. This is powerful. There have been numerous accounts of issues in the JavaScript space of package creators publishing new versions of a package that is a minor or patch that actually end up breaking API contracts. That causes many issues and can lead to a refactor or having to change code that you were not expecting to modify. That can be avoided with how smart the Elm package system is. I think it could even be used as a tool to teach people how semantic versioning works in practice.

To quote directly from their homepage:

Elm can detect all API changes automatically thanks to its type system. We use that information to force everything in our package catalog to follow semantic versioning precisely. No more surprises in PATCH releases!

There are currently about 554 packages. This was calculated by going to package.elm-lang.org and running the following in the console:

document.querySelectorAll('.pkg-summary').length;

It is growing and I really like the guidelines for creating and publishing a package.

Success Stories

A Swedish startup that decided to use Elm from the beginning for their project and they describe the benefits and output of that decision.

NoRedInk has been using Elm in production for over a year now (if my math is right). They talked about the experience of running it in production for 6 months back in February.

Futurice used it and wrote up their success around using Elm and how it helped their code base.

Conclusion

Elm is definitely on the right track. I think that if you are trying to figure out what to use for your next project, you should give Elm a try. You can even use it with existing projects due to the interoperability with JavaScript. It has a lot of benefits and lasting positive effects on a team and code base.