This is part 1 of the series IHP with Elm
Elm was my gateway drug into type-safe functional programming. It's such a good tool for making robust frontends. Writing big projects in React and TypeScript honestly bums me out because of it.
I have always wanted have to have the equivalent type-safe joy on the backend like I have with Elm.
Now I have it all, with SSR included and an amazing developer experience 😍
IHP is a new web framework that has opened a wide door for the web development community to get into Haskell. Like Rails and Laravel, it's great for quick prototyping, well documented and easy to use.
It even has the pipe operator (
|>) included making it even more similar to the Elm syntax.
Disclaimer: This tutorial should work for Mac and Linux. If you develop on Windows, it might not work without some minor tweaks on your own
Create a new IHP Project
If you haven't installed IHP already, make sure you do. It's surprisingly easy to get going.
Start a fresh IHP project for this tutorial.
To verify the app is working, cd into the
ihp-with-elm folder and run
.gitignore as soon as possible to avoid pushing unwanted stuff into git.
Initialize node and elm
default.nix file in the root folder, add
To update your local environment, close the server (ctrl+c) and run
Then initialize Node.js and elm at the project root.
For this tutorial, we will rename the
src folder that elm generated into
Set the source directories folder to "elm" in
Getting the Haskell template ready
Let's start writing the Elm entrypoint into the Haskel template.
Web/View/Static/Welcome.hs and replace all the html inside the HSX in
If your IHP app is not already running, run it with
./start and see the output on
As you see, Elm has not been loaded, because we naturally haven't written any Elm code yet. Let's close the server (ctrl+c) and do that now.
Setting up Elm
node-elm-compiler for compiling and
elm-hot for hot reloading in development.
You could do it all without a bundler like Parcel. IHP discourages bundlers, and I agree that it's not always necessary.
Still, Parcel provides valuable niceties like tight production minification and good hot reloading in development, so I prefer to use Parcel when things get a bit more advanced.
Main.elm in the elm folder:
elm/index.js should look like this to initialize the Elm file.
Finally, lets' insert the code for
Add the scripts for building the app both in production and development into
Then replace the
start script in
package.json and add accordingly:
There you should have it! Elm in Haskell with hot reloading and the Elm debugger is ready for you in the bottom right corner. Beautiful!
Build for production
When pushing your IHP app to production, you need to make sure that it builds the Elm applications.
Go to the
flatpickr because we are using the datepicker, but other than that, Turbolinks seems to complicate the Elm loading and jQuery gives us nothing Elm can't give us.
We're keeping bootstrap css just so we don't need to do any styling for this tutorial.
Put this code at the bottom of the
Makefile to build Elm in production.
It should now be ready to ship to production for example to IHP Cloud.
For a complete overview of what has been done, see the diff from a fresh IHP install.
Things I don't use Elm for in IHP
IHP gives you HTML templating (HSX) with pure functions, very similar to Elm. In that regard it's partially overlapping with Elm.
It can be a blurry line for beginners, so here are my recommendations for how to set those lines.
- Use HSX for forms. Forms are pretty much always a bigger pain written in app code. If you have been living in the Single Page App world for a while, you will realize forms written in normal HTML are not that bad. IHP gives you a convenient way of writing forms with server-side validation.
- Elm is great for making advanced custom form fields
- Do you want the content to have SSR for search engine optimization? Use HSX.
So unless you really want to write a full Single Page App, Elm should be used with restraint in IHP, for only specific supercharged parts of the site.
Most sites are actually better off outputting just HTML and CSS.
I want to take this application further in future posts showing you how to interact between IHP and Elm through flags, http requests and setting up a good widget architecture.