Skip to content

🌱 Building a better Elm Land

Written by Ryan on December 20th, 2022

What's new in Elm Land?

It's been two months, and a lot has happened for Elm Land. Our official Discord server has grown to just over 100 members. I want to start by highlighting some of the great projects shared in the #cool-projects channel by our community:

Seeing folks post screenshots and links to GitHub repos has been so exciting to see.

If you are using Elm Land for making games, apps, or even using it at work– be sure to share your experience with us in the Community Discord. I'd love to feature your project in the next release!

After seeing all the cool things being made Elm Land– it's time for me to share my own #cool-project ...

Elm Land v0.18.0 📦

Over the past few months, I've been working to tackle some of the key developer experience challenges I experienced when designing elm-spa, the predecessor to Elm Land.

Here are the three areas where Elm Land v0.18.0 has improved:

  1. Missing framework features
  2. Better examples, guides, and docs
  3. Community-driven features

Let's dive into each of these three areas together!

Stateful layouts

The biggest pain point I wanted to address with the new release is making it easy to reuse navbars, sidebars, or other UI layout onto an existing page. In the previous version of Elm Land, this was easy for simple layouts. The real challenge was wiring up layouts that track state between each of these pages.

With the new Layouts API, folks can create interactive, stateful layouts and share them across their application. We can see how this works with the new "User auth" example:

A demo of a reusable sidebar layout

In Elm Land v0.18.0, not only is the view code for that layout controlled in a single file, but the update logic for the "Sign out" button is also handled in one place:

elm
module Layouts.Sidebar exposing (..)

-- ..

update : Msg -> Model -> ( Model, Effect Msg )
update msg model =
    case msg of
        UserClickedSignOut ->
            ( model
            , Effect.signOut
            )

-- ...

Any page that wants to use this sidebar layout can opt-in via the Page.withLayout function:

elm
module Pages.Home_ exposing (..)

-- ...

page : Auth.User -> Shared.Model -> Route () -> Page Model Msg
page user shared route =
    Page.new
        { init = init
        , update = update
        , subscriptions = subscriptions
        , view = view
        }
        |> Page.withLayout (layout user)


layout : Auth.User -> Model -> Layouts.Layout
layout user model =
    Layouts.Sidebar
        { sidebar =
            { title = "Dashboard"
            , user = user
            }
        }

For more detail on how to build your application with the new layout system, be sure to check out the official User Authentication example.

It will walk you through building a hands-on example from scratch. This includes things like local storage, talking to a backend API, and creating the layout we highlighted above!

Catch-all routes

In the "Hello, world!" announcement back in October, I shared that Elm Land will earn the 1.0 release when it can build GitHub from scratch. With the addition of catch-all routes, we're getting one step closer to that goal!

On advanced apps like GitHub, sometimes user-defined content determines the length of the URL path. Here's a screenshot of the "code explorer" page, where the URL reflects your current position in the filesystem:

GitHub's code explorer page, showing a folder in the Elm Land repo

Elm Land v0.18.0 comes with a new enhancement to the file-based routing system to make pages like this possible.

This isn't a new idea by any means, Elm Land drew it's inspiration from popular JavaScript frameworks that solve the problem really well.

After exploring how this was done in Next.js, Nuxt.js, SvelteKit, and elm-pages, Elm Land was ready to tackle this problem, too!

Here's how you can create a page like the one we see GitHub use above, using the official Elm Land CLI:

The output of the "elm-land add page" command, creating a new file

This new routing update also comes along with a great feature recommended by @duncanmalashock: The elm-land routes command!

They had a positive experience with Ruby on Rail's "bin/rails routes" command, which helps folks see all the routes for an application at a glance. For that reason, Elm v0.18.0 ships with its own routes command:

The "elm-land routes" command, listing 5 routes in an example application in the terminal

TypeScript support

The last big feature I want to share is the zero-configuration TypeScript support. Adding first-class TypeScript support means you can get a higher level of confidence when working with NPM, environment variables, or other existing JS codebases. Using JavaScript is still 100% supported– but upgrading to TypeScript is as easy as renaming src/interop.js to src/interop.ts.

If you'd like to add custom TypeScript configuration to your Elm Land project, you can add the standard tsconfig.json right alongside your elm.json file.

Elm Land's built-in development server will automatically emit any TypeScript compiler errors to your browser as you code. If you are building for production, we'll also compile your TypeScript project and report any errors as a part of the standard elm-land build command.

( No need to roll your own TypeScript build setup– we've got you covered! )

The latest release also took a closer look at how to provide Elm-quality error messages when you encounter build errors with JavaScript, TypeScript or NPM. Here's a quick visual of an error message you might encounter in practice:

The "elm-land build" command, showing a helpful error reminding users to run npm install

New guides and examples

Elm Land has a big focus on making things approachable and easy to understand for newcomers to the Elm language. When I was first learning, having concrete examples and guides for how to build real projects were super helpful to me.

With the latest release, we also shipped an in-depth "User Authentication" guide!

This guide offers solutions to some common problems you might encounter when building your next web application:

  1. Local storage – Working with JavaScript to store a user token
  2. User auth - Using the Auth.elm module to only render pages when a user is signed-in
  3. Using layouts - How to use the new layouts system

In addition to the in-depth guide, this release comes with a handful of example for folks who are trying to customize or enhance their application.

  1. Using Elm UI
  2. Using Elm CSS
  3. Using a CSS preprocessor, like SCSS
  4. Reporting production errors to Sentry
  5. Customize the not found page

Those are just a few! Check out the examples folder on our GitHub repo for the full list.

Ultimately, I'd love to see each of these examples as their own in-depth guide– but I want to get the latest release out for the Elm Land community.

It's important to me that I can release this version and get meaningful feedback as I go! I'm looking forward to seeing more examples of how folks are using Elm Land in their own applications.

Community-driven features

This release also comes with a handful of features that came from the Elm Land community! If you ever want to contribute, our Discord comes with channels like #suggest-a-feature and #report-a-bug.

Those two channels played a huge role in adding of the following highlighted features:

Hash-based routing

Some web hosting environments have constraints that make hosting apps with multiple pages difficult. @mattcheely tackled this problem head-on by adding hash-routing support to the project. Now any Elm Land user can easily opt-in to having their single-page apps use URLs like /#/blog/123 in case /blog/123 doesn't work with their workplace's hosting setup.

Support for <script> tags

Community member @thomasin opened their first Elm Land PR which made it possible to easily drop in <script> tags to the elm-land.json file. This allows folks to add CDN links to JavaScript just as easily as we can add CSS tags.

This was another great example of a conversation that started in Discord and became a real feature in the framework!

A new Elm NPM package

Simon Lydell (@lydell) is exploring a new way to distribute the official Elm binaries via NPM. His latest NPM package is internally used by Elm Land to fix issues for folks using M1 or M2 MacBook Pros. Huge shoutout to Simon and Mario Rogic for their work on this package– it's solving real issues for real users!

CLI improvements

Folks in the #report-a-bug channel reported issues when running --help, so we've added detailed help commands for each CLI command. Here's an example of running it for the elm-land init command:

The "elm-land init --help" command, showing more detailed instructions

Be sure to try out this --help flag on any Elm Land command if you ever get stuck!

What's next?

Elm Land is just getting started. To see what's next on the project, here are some public resources for you:

  1. Check out the official roadmap on GitHub
  2. Follow the Elm Land project on Twitter
  3. Come join the Discord community and share your ideas!

For the next release, I'm hoping to refine the error messages and get a start on the plugin ecosystem. I hope everyone has a wonderful December and a Happy New Year!

Let's be mainstream! 🌈

Made for you with ❤️