[UPDATE: I’m adding to these notes as I learn more. Last update: 8 Oct 2018]

This morning, my Twitter timeline was abuzz with exciting news: Elm 0.19 has been released!

The official announcement focused on the big ticket items: impressive reductions in the size of the generated JavaScript and no less impressive improvements in compilation speed. Those are very good things, but I wanted to provide a more comprehensive list (including some stuff that didn’t make it into the release notes either).

Changes

Language changes

Nothing major has been added but a few things have been removed in order to simplify the language:

You won’t be able to export/import a subset of constructors anymore - it’s either MyType or MyType(..) now.

or now. No more custom operators - you will need to define regular functions instead.

Some existing operators were removed: tuple creation operators (use lambdas instead), Platform.Cmd.(!) (create the model-cmd tuple explicitly instead), and % (replaced by modBy ).

(create the model-cmd tuple explicitly instead), and (replaced by ). Tuples limited to a max of 3 elements - you’ll need to use a record for anything larger.

Variable shadowing is no longer allowed.

Changing the type of a field in a record when updating is no longer allowed.

You won’t be able to update the same field twice in a single record update like this: { m | field = f x, field = g y } .

. Finally, new escaping syntax for Unicode in strings: \u{00B1} .

Again, no major changes but things have been tidied up:

Only one binary called elm , other binaries became commands (eg elm-make is now elm make ).

, other binaries became commands (eg is now ). elm-package.json got renamed to elm.json .

Additionally, outside of the core Elm tools, elm-live has now been updated to support Elm 0.19. Also, vscode-elm (the Elm plugin for Visual Studio Code) now has some initial support for Elm 0.19.

To use elm-test with 0.19, you need to install it with npm install -g elm-test@beta . You don’t need a separate elm.json in the tests directory, but you need to add this to your project’s elm.json :

"test-dependencies": { "elm-explorations/test": "1.0.0 <= v < 2.0.0" }

Compiler and code generation changes

This was an area that got the most attention in this release. Big improvements here (you can read about them in the official announcement):

Function level dead code elimination with --optimize flag (note that this disables debugging stuff).

flag (note that this disables debugging stuff). Much better compile times (2 seconds reported for a 50K line code base).

There should be less need for lazy calls when working with recursive types like decoders and parsers.

calls when working with recursive types like decoders and parsers. The --warn flag to elm make is gone for now - not really on purpose but due to time constrains (https://github.com/elm/compiler/issues/1752#issuecomment-415068356).

Additionally, native code is no longer allowed for packages (with the exception of whitelisted code under elm-lang and elm-explorations ). This was a source of some controversy but this is part of what made the improvements in code generation possible.

Libraries

There are quite a few changes in the core libraries (thanks to Ilias for pointing out some of these to me):

The virtual-dom package now allows synchronous event handling, solving the issue with lost input due to fast typing, among other things. The sequence of sending an event from HTML, getting a call to update , then sending a value to a port and handling it on the JS side can now happen synchronously. Event handling is also more flexible.

package now allows synchronous event handling, solving the issue with lost input due to fast typing, among other things. The sequence of sending an event from HTML, getting a call to , then sending a value to a port and handling it on the JS side can now happen synchronously. Event handling is also more flexible. Some packages were moved from elm-lang to elm .

to . There is a new API for working with the DOM in the Browser.Dom package.

package. Basics.toString has been replaced with three functions to help cut down on some types of bugs: Debug.toString , String.fromInt , and String.fromFloat .

has been replaced with three functions to help cut down on some types of bugs: , , and . Html.beginnerProgram has been replaced with Browser.sandbox , while Html.program has been superseded with Browser.element and Browser.document .

has been replaced with , while has been superseded with and . There is an improved API for Time and Date .

and . There is a simpler API in the url-parser package (which also got moved to elm/url ).

package (which also got moved to ). Color module got removed.

module got removed. A few functions were removed: flip , curry , uncurry , and rem .

, , , and . A number of bugs fixed in Array .

. The random number generator has been switched to PCG, which has better properties (https://github.com/elm/core/pull/778)

String.map / foldl / foldr / uncons now consider Char to be a Unicode codepoint rather than an UTF-16 byte.

/ / / now consider to be a Unicode codepoint rather than an UTF-16 byte. String.toInt no longer recognises the 0x prefix.

no longer recognises the prefix. Lastly, it’s no longer necessary to maintain a separate elm.json in tests/ (everything is handled within the project’s elm.json ).

Runtime performance

List.foldr is 30% faster (which means that List.map , List.filter and List.append are faster too).

is 30% faster (which means that , and are faster too). Dict has 170% faster inserts and 30% faster removals

has 170% faster inserts and 30% faster removals Set has comparable improvements to Dict as it is a thin wrapper around it.

has comparable improvements to as it is a thin wrapper around it. Random functionality has speedups of 20% to X00% on different operations.

functionality has speedups of 20% to X00% on different operations. Char values and values of types like type Height = Height Float are unboxed (which makes equality checks faster, among other things).

Installation/upgrade

NOTE: make sure that the packages you need are updated for Elm 0.19 before upgrading. At this point, many packages won’t be!

To install Elm 0.19, you can use one of the installers listed in the guide, or you can install it from NPM. It’s also available on Homebrew.

If you’d like to run Elm 0.18 and 0.19 side by side, your best bet is probably to install Elm locally, on a per-project basis. You can install 0.18 locally with npm install elm@0.18.0 .

When it comes to upgrading existing code to the new version of Elm, a tool called elm-upgrade will be able to help automate some of it. It’s been updated to perform the 0.18 -> 0.19 upgrade. Note that it also requires elm-format .

Additionally, Tomáš Látal created a handy tool to check whether your dependencies have been updated for Elm 0.19. You paste the contents of your elm-package.json into it, and it reports the status of the packages listed there.

One more thing to note: Ellie is now using Elm 0.19.

Want to know more?

Here is some further reading material if you’d like to learn more about Elm 0.19:

Official announcement

Upgrade instructions

Elm 0.19 brings better collections

MiniLatex experience report for Elm 0.19

Updated official Elm guide

Native code in Elm 0.19

The rationale for removing custom operators

Practical Elm book and Elm 0.19

I’ll be revising Practical Elm to be up-to-date with all the changes in Elm 0.19.

If you’ve already bought Practical Elm - don’t worry, you’ll get the updates free!