wolf4earth

wolf4earth

Elm-pages: A statically typed site generator

I’m currently in the process of rebuilding my personal website/blog from scratch. At the moment my website is using hugo, and while I think hugo is great to quickly build a site following a specific structure (blog posts etc.) I felt it was super fiddly to add additional pages which don’t fit into this structure.

As such I was looking for something more flexible which at the same time would be interesting to use. So I googled for static site generators, sifted through all the different options on StaticGen (which is a great ressource btw) and came across …

Announcement blog post here

I’ve dabbled with elm quite a few times in the past and visited the occasional meetup in Cologne, but I never built something of significance. So I thought: what is better than building my own website with it without having to build it completely from scratch!

While I’m not quite done yet, I’ve invested a bunch of hours in elm-pages and I must say: it’s a joy. Here are some of the great things it offers:

Compiler errors for asset typos

By running elm-pages develop you get a generated (and live updated) Pages module which contains references to files in your content/ and images/ folders, which get exposed as a pages and an images function.

Let’s assume I have the following files in images:

images/
  logo.png

images/article/foo/
  splash.png

I can now reference the path to these images by using images.logo or images.article.foo.splash. And in case I have a typeo (e.g. lgo instead of logo) the very helpful elm compiler will tell me about it.

HTML generation in pure elm

This is of course a personal taste thing, but the HTML generation for your pages gets written in pure elm. So if you want to use markdown for your articles, you write the support for markdown in elm. In the case of markdown this mostly consists of a bit plumbing to call into the elm-markdown package.

It also means that you can write the actual HTML generation code using the great elm-ui library.

But the real power of this approach only becomes apparent when you try to add support for a different kind of page type (for example a Talk or Project page type) or want to support a new document type (such as AsciiDoc) to write your blog posts. Again you do all of this by writing pure elm code.

All this time you have the awesome elm compiler helping you with this, so if you add a Project page type (by adding a ProjectMetadata option to the Metadata union), the elm compiler will tell you exactly where you need to make changes to support this new type.

Extend your site with statically typed confidence!

First class SEO (search engine optimization) support

I can’t say much about this yet, but elm-pages ships with built-in type-level support for SEO. Take a look at this part of the announcement blog post.

Most Liked

wolf4earth

wolf4earth

I’m not deep enough in the elm community to comment on the usage of elm-ui in any known pages.

I know for a fact that elm-ui generated some waves, and Richard Feldman mentioned it in this talk as a potential “killer app” for elm, like rails was for ruby:


What I can say to the comparison with Jekyll is limited to my experience with Hugo. I’ve used Jekyll only briefly but from what I can tell it’s quite similar to Hugo, from a philosophy standpoint. As such I’ll assume that a comparison between elm-pages and Jekyll is fundamentally similar to a comparison between elm and Hugo.

Given this is true, I can say that the fundamental approach of elm-pages and Hugo/Jekyll differs in how they actually generate the final result: HTML pages.

Jekyll and Hugo are both based on templates. As such you more or less write HTML and sprinkle some template magic on top (speak partials, loops, etc.), with all the pitfalls this brings to the table (typos, duplication, etc.).

With elm-pages the generation is based on code, you don’t deal with templates when using elm-pages. This shouldn’t be surprising if you’ve ever had contact with elm before: when building a page with elm, you stay in “elm-land”.

This has a number of advantages and of course also disadvantages. Advantages include:

  • static typing: elm has a great type system and extremly helpful compiler errors (seriously, they’re amazing)
  • composability & flexibility: as you’re writing code you’re free to split and reuse it as you see fit
  • context switching: no need to switch between HTML and code (and even CSS if you want)
  • static HTTP requests: this is a neat feature of elm-pages, basically you can send an HTTP request at build time and then transform the response to content for your page (I’m not aware of any Jekyll/Hugo equivalent)

But as said before, there are of course disadvantages:

  • themes: AFAIK elm-pages doesn’t have a “theme” functionality as Jekyll or Hugo do
  • plugins: as elm-pages is by far not as popular as Jekyll or Hugo, so of course this is falling behind, on the other hand as everything is “just elm” you’re free to use all the elm libraries out there

I think all of this boils down to this:

elm-pages gives you the tools to build a statically generated website but requires a DIY attitude, Jekyll and Hugo offer an opinionated approach to static website building but require buy-in into their way of doing things.

At the end of the day it’s a question of how much flexibility you want to trade for productivity. And for me this question is currently clearly answered with “please give me more flexbility”.


Does this paint a clearer picture, @AstonJ?

wolf4earth

wolf4earth

It’s roughly at 5:20:

Popular Frontend topics Top

AstonJ
Anyone have any thoughts about Preact? They’re saying it’s a “Fast 3kB alternative to React with the same modern API”… A different kin...
New
New
First poster: AstonJ
A new Svelte blog post/announcement has been posted! Get the full details here: What's new in Svelte: May 2021
New
mrmurphy
The situation Hi there! I’m working on a live view app right now that encrypts sensitive user content (text and images) using the browser...
New
First poster: bot
A new Angular blog post/announcement has been posted! Get the full details here: https://blog.angular.io/build-more-accessible-angular-...
New
mafinar
Just like I did one on Tailwind some time ago, I am going to play with AlpineJS the next few days. It’s a nice little JS framework that ...
New
First poster: bot
Instead of pulling you into a library-specific magical world, CalDOM let you fully access the DOM directly while keeping the reactivity. ...
New
First poster: bot
Tailwind v3.0.12 has been released. Link: Release v3.0.12 · tailwindlabs/tailwindcss · GitHub
New
First poster: bot
Preact 10.8.0 has been released. Link: Release 10.8.0 · preactjs/preact · GitHub
New
New

Other popular topics Top

AstonJ
What chair do you have while working… and why? Is there a ‘best’ type of chair or working position for developers?
New
PragmaticBookshelf
Design and develop sophisticated 2D games that are as much fun to make as they are to play. From particle effects and pathfinding to soci...
New
AstonJ
SpaceVim seems to be gaining in features and popularity and I just wondered how it compares with SpaceMacs in 2020 - anyone have any thou...
New
brentjanderson
Bought the Moonlander mechanical keyboard. Cherry Brown MX switches. Arms and wrists have been hurting enough that it’s time I did someth...
New
AstonJ
poll poll Be sure to check out @Dusty’s article posted here: An Introduction to Alternative Keyboard Layouts It’s one of the best write-...
New
dimitarvp
Small essay with thoughts on macOS vs. Linux: I know @Exadra37 is just waiting around the corner to scream at me “I TOLD YOU SO!!!” but I...
New
PragmaticBookshelf
Author Spotlight James Stanier @jstanier James Stanier, author of Effective Remote Work , discusses how to rethink the office as we e...
New
PragmaticBookshelf
Author Spotlight Mike Riley @mriley This month, we turn the spotlight on Mike Riley, author of Portable Python Projects. Mike’s book ...
New
New
husaindevelop
Inside our android webview app, we are trying to paste the copied content from another app eg (notes) using navigator.clipboard.readtext ...
New