Bootstrapping an Elm Project

Elm is a delightful language for building reliable web applications. It’s a language that gets compiled to JavaScript and so is used to build applications that run in a web browser.

In this post, we’re going to explore different ways of starting an Elm project, starting with the simplest and moving on to setups with more advanced features such as hot-reload in development.

Let’s get started!

Prerequisites

Before we get started, please make sure to Install Elm

To confirm if you have Elm installed, you can try running the interactive repl using the elm repl command. If you get a prompt such as the one shown in this image, you’re good to go ūüĎć

Elm repl

Elm CLI

This is the officially supported way of creating a new Elm project.

  1. Create a new directory where your project will live

    mkdir my-awesome-elm-project

  2. Navigate to the newly created directory

    cd my-awesome-elm-project

  3. Run elm init inside this directory and you should get a prompt like the one below:

Elm init prompt

  1. Press the Enter key and it should create an elm.json file in the current directory. A src directory will also be created.

It is a good idea to read through the linked resource that talks more about starting new Elm projects

  1. Let’s start by creating a new Main.elm file in the src directory. Once we’ve created the file, let’s add some Elm code that should show us the classic "Hello World!" message once we run it.
module Main exposing (main)

import Browser
import Html exposing (h1, text)

main =
  h1 [] [ text "Hello World!" ]
  1. To run the code, let’s run elm reactor in our directory and it should start a new local server at http://localhost:8000. elm reactor is the simplest way to get started running Elm code.

  2. Once you navigate to http://localhost:8000, you should see an interface like the following.

Elm Reactor

Click on the src link, then Main.elm and you should be greeted by our "Hello World!" message.

And that’s it! We’ve successfully created a project the elm init command and run it using elm reactor.

Pros:

  • Easy to get started
  • No external dependencies apart from elm itself

Cons:

  • Manual reloading once we make changes

Elm Make

This is an extension of elm reactor and includes the ability to compile our Elm code to static HTML.

Using the same project from our previous section, we can compile the project using the command:

elm make src/Main.elm

Once we run this command, an index.html file will be generated in the current working directory, and if you open it in a web browser, you should see the same "Hello World" message.

I don’t have lots of experience with elm make so that’s as far as I’ll go with it.

Parcel

Parcel is a "Blazing fast, zero configuration web application bundler" and is my personal favourite to get started with an Elm application quickly. It handles compiling your Elm code to JavaScript and is super easy to get started with.

You can create an Elm application compiled by Parcel in a few simple steps:

  1. Install Parcel

    yarn global add parcel-bundler or npm install -g parcel-bundler

  2. Follow the instructions in the Elm section of the Parcel website, which involves:

  • creating an index.html file with the following contents:
  • creating an index.js file with the following contents:
import { Elm } from './Main.elm'

Elm.Main.init({
  node: document.querySelector('main')
})
  • creating a Main.elm file with the following contents:
module Main exposing (main)

import Browser
import Html exposing (h1, text)

main =
  h1 [] [ text "Hello, from Parcel!" ]
  1. To run the application, run the command: parcel index.html

I love this setup so much that I’ve created my own starter project based on Parcel. Feel free to check it out on GitHub

Pros:

  • Easy to get started with
  • No manual configuration needed ūüí™
  • Hot reload included out of the box
  • Easy to get started with JavaScript Interop

Cons:

ūü§∑‚Äć‚ôÄÔłŹ

Notable Mentions:

This is not meant to be a comprehensive list, and any suggestions/additions are welcome in the comments section below.

I hope these options are useful for you when starting out your next Elm project ūüöÄ

How to Introduce Elm to a React Codebase

How to Introduce Elm to a React Codebase

Elm is a delightful language that helps¬†make¬†web applications¬†more reliable¬†by eliminating runtime exceptions. I find it extremely productive working with Elm, and would like to be able to use it in a JavaScript¬†codebase¬†without breaking the existing application or having to rewrite it altogether. However, it’s not obvious how to try out Elm in a small piece of the application, just enough to¬†evaluate how well it works. This is what we will address¬†in this article by exploring how to add a new feature to a React codebase with Elm.

Continue reading “How to Introduce Elm to a React Codebase”

From JavaScript to Elm: A Blissful Journey

From JavaScript to Elm: A Blissful Journey

When building web applications with JavaScript, there are thousands of tools and frameworks to choose from. Most of these tools aim to make developing with JavaScript easier and more productive, and most of them help web developers¬†achieve that. However, sometimes the language itself is the constraint.¬†If you have built web applications¬†in JavaScript, there’s a good chance you’ve experienced errors like Uncaught TypeError: Cannot read property 'x' of undefined that end up taking lots of time to debug. The language does not help you catch these errors early enough in the development cycle, and they usually end up being discovered too late,¬†mostly¬†by your users reporting that something is not working.

What if you could release your web app with the confidence that you would never get any runtime exceptions again? What if every time you needed to refactor code, you could do it confidently knowing you have a compiler that would let you know of any errors and suggestions on how to fix them? What if you could get all these benefits today, right now?

Welcome to the world of Elm.

Elm is a language written specifically for building reliable web-based user interfaces and targeted towards the needs of modern frontend applications. It compiles to JavaScript, which makes it usable in web browsers, and is famous for its promise of¬†No Runtime Exceptions.¬†With Elm, you are guaranteed that once your app compiles, there won’t be any crashes and you can devote your time¬†to deal with the things that matter. Let’s dive in and explore this language and what it has to offer.

Reliability

The best part of using a language with a compiler is you never have to deal with minute details such as typos and using undefined functions. You leave those to the compiler. Think of a compiler like a helpful assistant that helps you with the simple stuff and leaves the important¬†logic details¬†to you. One thing’s for sure; you will make mistakes from time to time, and the compiler is here to make you aware when you make these mistakes and how to fix them.

Let’s see how the compiler can be helpful with a real example. Let’s assume we want to add up all the numbers in a list and while creating¬†the list, we happen to make¬†the slightest of mistakes by including¬†one of the numbers as a string.

If we were doing this in JavaScript, this is how this might look:


[0, 1, 2, '3'].reduce(function(acc, val) {
    return acc + val;
}, 0);

This will return 33, not quite the result¬†we expected¬†ūü§Ē

Now let’s try to do the exact same computation in Elm and see what happens.

Screen Shot 2017-04-26 at 5.36.23 PM

The code won’t even run. Elm expects all items in a list to¬†be of the same type, and it notices that it is being asked to add numbers and strings, which is an ambiguous operation. The Elm compiler realizes our mistake and points out¬†the exact list entry that is causing the mismatch¬†and even adds some helpful hints and a link to the docs to explore things further.

This is exactly what I want in a language. I¬†obviously made a silly mistake, which JavaScript ignores and gives me a result of 33¬†, which isn’t really that helpful. I would prefer to know that I made a mistake and fix it rather than get a result that is obviously wrong.

This is what makes developing apps in Elm such a pleasant experience, since you always know the compiler has got your¬†back. There are no surprises after you’ve released your app, and no more sleepless nights debugging why the sum of ‚Äč‚Äč1,¬†2 and 3 is ‚Äč33¬†ūüėÄ

A Well-Defined Architecture

Elm has a standard¬†way of organizing your application, and this pattern is called¬†The Elm Architecture. You’ll notice this pattern over and over again as you¬†explore Elm apps.¬†It enables you to separate your application into three parts:

  • Model ‚ÄĒ the state of your application
  • Update ‚ÄĒ a way to update your state
  • View ‚ÄĒ a representation of your¬†model as HTML

I find this to be a solid way of structuring¬†web applications. The first part is the model, which holds your app state. Going through the Elm architecture examples really helps in showing how to model different types of data. I’ve also found union types to be helpful in creating custom types that express your intent more clearly.

The update section is how you change your app state. It receives an intent to change the state, computes the new state from the old one and returns the updated state object. Since everything is immutable in Elm, we are always returning a new state object after each computation, and never modifying the old one. This enables us to get a trail of how our model changes over time as people interact with it.

This concept makes debugging trivial since to reproduce a particular state, we can record the sequence of actions that were taken and apply them to the model to get to the state we want. This is the concept behind innovations such as the time traveling debugger, which you can check out in action in this Mario game.

Lastly, there’s the view¬†which is a¬†visual representation of the¬†model on the screen. Anytime the model changes, the view is updated automatically, and Elm is blazing fast at this.

The good news is that the JavaScript ecosystem is generally heading towards this direction with ideas such as a single state tree, reducers and pure view functions. In fact Redux is modeled after the Elm Architecture.

Try it

The best way to experience Elm¬†is to try it for yourself. Even if you don’t plan on using it on a daily basis, try it. Start with The Elm Architecture and take it from there. It will have a positive effect on any¬†code you write in future. If it seems¬†hard and confusing the first few times,¬†give it five minutes.

The Elm community is pretty welcoming and you should join the Elm Community Slack and ask any questions that arise.

I can’t wait to see what you build with Elm¬†ūüėé

Featured Image Credits: https://unsplash.com/@sanfrancisco?photo=OVG7eFTB48c