Don't split up your codebase before you need to: The most useful Elm tip that I shouldn't have ignored
Tags: elm
Published: 2018-07-13 09:21:22

---
title: Don't split up your codebase before you need to: The most useful Elm tip that I shouldn't have ignored
published: true
description: "A short post intended to help people building their first Elm application to avoid the headaches I gave myself."
tags: elm
---

My background is mostly in JavaScript, and when building JavaScript applications, I like to have them separated pretty heavily. This came about after seeing one too many `utilities.js` files that went on forever and had completely unrelated functionality, which I generally found to be very difficult to maintain. And this keen separation has been good - it's made life a lot easier. 

This made it hard to approach another language with a different mindset. I _knew_ that seasoned Elm developers advised against subdividing models and separating modules prematurely, but I thought "no I can't just keep everything together, that's going to be way too difficult to manage". So I diligently set about making sure that I had a series of nested state machines which each managed their own state, and a parent state machine that mapped all of the messages that came out of the application and called their `update` functions correctly, and I was mostly happy. My views had to do `Html.map` more than I'd like, because they were having to map `X.Msg` (and `Y.Msg`, and `Z.Msg`, and so on...) back to the parent state machine's message type, but it felt okay. 

Then I came to adding a command to fetch some data from a REST endpoint. Things started to feel a little less "okay" here, because all of a sudden I had a command that was being called in the parent state machine's module when the application was initialised, and passing the result of it down two levels to call a child state's `update` function. This smelled pretty bad, but, it worked: when the application started up, the data was fetched, processed, and passed to `update` correctly. 

Then I came to trying to re-fetch that data from a message that was passed by the state machine that actually used it. Things got _very_ messy from here, and the way that I had organised my code in order to make my life easier ended up causing me major problems. I found it difficult to see a sensible path forward for this functionality, and I hadn't even really written all that much code! 

## Undoing my own mess

When I felt like I was fighting against the tool, I decided to ask the community on the [Elm Slack workspace](https://elmlang.herokuapp.com), and someone there suggested that I wouldn't have this problem if my message types were all aligned; which of course, they only _weren't_ because I'd approached this as if it were a JavaScript application. 

Thanks to the ease of refactoring that comes with Elm, I figured I'd give this a try (even though it felt alien to me to do so, to be honest) - I made a new module that held all of my messages, and combined all of my previously separate `update` functions into one, fixed up the changes I'd made to the application's model along the way - as I realised that the model had been laid out in order to facilitate my file structure - re-compiled, and re-ran the application. 

All good so far, everything works as it did previously. So, now I need to actually make the change to allow for data to be fetched when the user requests it - not _just_ on application load - and I think to myself "okay, where do I have to make this update in my new structure"...before instantly realising "oh, the _one place where updates can happen_".

It turns out, this isn't unmanageable at all - in fact, it's _much_ easier to reason about this entire application now, and even easier than that to know where you need to make changes whenever you're adding a new feature. Maybe soon I'll think "okay `x` needs to be managed in isolation", but at least I'll only be adding that extra complexity _when it feels beneficial_, rather than adding it _because I think I'll probably need it to be that way_. If I'd avoided this early subdivision, I'd have saved myself a lot of time trying to make something work in a way that it probably _shouldn't_, so learn from my mistakes: if tutorials, articles, and seasoned Elm developers tell you to leave splitting up your application until later, listen to them!