We use cookies and other tracking technologies to improve your browsing experience on our site, analyze site traffic, and understand where our audience is coming from. To find out more, please read our privacy policy.

By choosing 'I Accept', you consent to our use of cookies and other tracking technologies.

We use cookies and other tracking technologies to improve your browsing experience on our site, analyze site traffic, and understand where our audience is coming from. To find out more, please read our privacy policy.

By choosing 'I Accept', you consent to our use of cookies and other tracking technologies. Less

We use cookies and other tracking technologies... More

Login or register
to publish this job!

Login or register
to save this job!

Login or register
to save interesting jobs!

Login or register
to get access to all your job applications!

Login or register to start contributing with an article!

Login or register
to see more jobs from this company!

Login or register
to boost this post!

Show some love to the author of this blog by giving their post some rocket fuel 🚀.

Login or register to search for your ideal job!

Login or register to start working on this issue!

Login or register
to save articles!

Login to see the application

Engineers who find a new job through Functional Works average a 15% increase in salary 🚀

You will be redirected back to this page right after signin

Blog hero image

Rapid Web Prototyping with Elm

Jonathan Reeve 24 November, 2021 | 5 min read

About

Developers typically encounter Elm when they want to make a dynamic web application—something Elm excels at. There are already great guides which introduce Elm for that purpose. The very first example in the Elm Guide is a counter app that lets you increment and decrement a number.

But maybe you haven't considered Elm for the use-case of rapidly prototyping a web page. In other words, what do you reach for when you want to create a static web page quickly? Do you use a static site generator, like Jekyll, Hugo, or Next.js? Or do you hand-write HTML, CSS, and JavaScript? Either way, Elm is an improvement. Elm is a functional programming language for the web, which replaces HTML, CSS, and Javascript. I want to show you how much of a joy it is to write, and how it can be your next tool for rapid creation of web pages.

The Problem

The problem with web development is that its fundamental languages—HTML, CSS, and JavaScript—each have their idiosyncrasies. Making a web page usually means being trilingual with these technologies and their syntaxes. HTML is verbose, and isn't programmable, which means you end up repeating yourself. Imagine if you're writing a list of three fruit. In HTML, that's:

<ul>
  <li>apples</li>
  <li>oranges</li>
  <li>bananas</li>
</ul>

Why can't we just write <li> for item in ["apples", "oranges", "bananas"]</li>? HTML isn't very DRY.

CSS has many of the same limitations. While new CSS features like CSS variables certainly mitigate the issue of code reusability, it still isn't a programming language. CSS nesting, for instance, is still a working draft, and not yet implemented in any browser. This is why there have been so many HTML and CSS preprocessors: SASS/SCSS for CSS, Pug for HTML. Each tries to make HTML and CSS into more of an actual programming language.

A further problem is that JavaScript is a bit of a mess. It's clunky, and not type-safe. This means that if you write some JavaScript, you're always in danger of unexpected input throwing exceptions. CoffeeScript and TypeScript were meant to solve these issues, but they only serve to add to your stack of preprocessors. Even if you write HTML with Haml, CSS with SASS, and JavaScript with CoffeeScript, you're still wrangling three languages. Some static site generators make a stack like that relatively easy, but generate a lot of complexity.

Introducing Elm

Enter Elm. It's a delightful language for modern web programming. Elm has Haskell-inspired syntax, and takes inspiration from other languages, as well. It's type-safe, but with optional type annotations. This means that errors are usually discovered at compile time, rather than at runtime. That means that if it compiles, it's very likely to run without errors from then on. The compiler error messages are friendly, and so is the community, which is very open and supportive. Even though it's a new language, it has seen a lot of adoption already in the industry, and has a ton of packages available for it. Elm compiles to HTML, CSS, and JS, so instead of wrangling those three languages (or three analogous preprocessor languages), you just write Elm, and it handles the rest.

Hello world

Here's the bare minimum web page you can make with Elm.

module Main exposing (..)

import Html exposing (..)

main = text "hello world!"

You can run this example here on Ellie, if you don't yet have Elm installed.

What's happening here?

  1. Ellie requires you to declare that your file is a module called Main.
  2. The function text, as well as the other Html functions we'll use, are in the HTML Module, which we have to import.
  3. Function calls in Elm look like they do in Haskell, so write text "hello world" instead of text("hello world") as it would look in Python-like languages.
Join our newsletter
Join over 111,000 others and get access to exclusive content, job opportunities and more!

Puppies or kittens?

Now let's prototype a toy web page, about whether puppies or kittens are cuter:

module Main exposing (..)

import Html exposing (..)
import Html.Attributes exposing (..)

main = main_ []
  [ h1 [ style "color" "red" ] [ text "Puppies or kittens?" ]
  , p [] [ text "This page considers the problem of whether puppies or kittens are cuter." ]
  , img [ src "https://placekitten.com/g/400/400" ] []
  ]

Run this example here on Ellie.

Here's what's going on here:

  • Lists in Elm look like this: [ a, b, c ]
  • HTML functions usually take two arguments: a list of attributes, and a list of contents: p [ attribute1, attribute2 ] [ element1, element2 ]. Thus, the main_ function has no attributes, but has three children: h1, p, and img.
  • CSS is written in the same way. style takes two arguments, the CSS selector, and its value.
  • Whitespace doesn't matter, so we can indent this any way that makes sense.

Functions

We can DRY out this website, by abstracting away functionality that repeats. For instance, if we want two kitten photos, instead of writing two <img src=""/> tags, we can write a function that will do both.

Functions that take parameters look like this: greet name = "Hello" ++ name ++ "!". The greet function takes the name argument, and inserts it into the greeting, such that calling greet "Jonathan" returns "Hello Jonathan!".

So if we want to have two images, one which loads a placeholder kitten image from https://placekitten.com/g/400/400 and another from https://placekitten.com/g/300/300, we can write that like this:

module Main exposing (..)

import Html exposing (..)
import Html.Attributes exposing (..)

kitten size = img [ src ("https://placekitten.com/" ++ size ++ "/" ++ size)
                  , style "border" "1px solid red" ] []

main = main_ []
  [ h1 [ style "color" "red" ] [ text "Puppies or kittens?" ]
  , p [] [ text "This page considers the problem of whether puppies or kittens are cuter." ]
  , kitten "400"
  , kitten "300"
  ]

Run this example here on Ellie.

Markdown example

Alternatively, you can write your site in Markdown:

module Main exposing (..)

import Html exposing (..)
import Html.Attributes exposing (..)
import Markdown exposing (toHtml)

content : Html msg
content = toHtml [] """

# Apple Pie Recipe

  1. Invent the universe. 2. Bake an apple pie. """ main = content

To run this example in Ellie, you should install the package Markdown using the sidebar to the left.

  • Triple-quotes """ are for multi-line literal strings.

I love it. How can I learn more?

Once you've outgrown Ellie, and want to build pages locally, download installers from here. Or install via npm if you already have node: npm install -g elm. That enables you to run elm build to generate your site from a Main.elm file.

The official Elm guide is also wonderful, and eminently readable. There's also the book Elm in Action, if you prefer learning from books.

Author's avatar
Jonathan Reeve
Computational literary analyst, digital humanist, English PhD student at Columbia.

Related Issues

open-editions / corpus-joyce-ulysses-tei
open-editions / corpus-joyce-ulysses-tei
  • Started
  • 0
  • 2
  • Intermediate
  • HTML
open-editions / corpus-joyce-ulysses-tei
open-editions / corpus-joyce-ulysses-tei
  • Started
  • 0
  • 2
  • Intermediate
  • HTML
open-editions / corpus-joyce-ulysses-tei
open-editions / corpus-joyce-ulysses-tei
  • Open
  • 0
  • 0
  • Intermediate
  • HTML
open-editions / corpus-joyce-ulysses-tei
open-editions / corpus-joyce-ulysses-tei
  • Started
  • 0
  • 1
  • Intermediate
  • HTML

Get hired!

Sign up now and apply for roles at companies that interest you.

Engineers who find a new job through Functional Works average a 15% increase in salary.

Start with GitHubStart with Stack OverflowStart with Email