What I Chose NOT to Build: Decision Points in My Elixir Training Platform
Five ways I avoided over-engineering while still making something students actually want to use
As any developer out there, I love to start pet projects. But for me they have a different weight: developing a pet project helps me to stay connected to my personal mission.
I’m constantly teaching and coaching people on how to develop better products, be it in CSM/CSD classes, as a consultant or as a mentor. I do have my share of stories to share during these events, but you know… while these stories are new and exciting for the students, I can’t say the same after repeating them a dozen times.
And besides… I need an excuse to touch code. :)
The Product
As a trainer, I try to create simulations so my students can learn by their own experience most of the time. That’s why in 2019 I created the card game Scrumchkin, for example. But since the pandemic, most of my training sessions have been online, which makes it really hard to replicate the same dynamic environment I had with the actual Scrumchkin cards in an in-person training.
So, I decided that my product would try to solve that problem:
The students should be able to learn complex subjects through dynamic experience and simulations.
It was a good fit after all: I have periodic classes where I can take the product to a field test and collect feedback and I have access to a community of trainers that could be interested in trying the product and providing a different kind of feedback.
As everything I needed was an excuse to start writing code, I was happy with that.
Decision: Pick an UI component library from the beginning and stick to it. You can change the whole thing later, if necessary.
Tooling decisions
I decided to avoid using a database at first, until I figure out what kind of data I want to store and how I want them stored.
Elixir (my go-to language) has something that does the job quite well: GenServers. I can use them to temporarily store data without having to resource to a database. The information will be there until one of three things happen:
I restart the server
An error occurs and the GenServer gets restarted
I terminate the GenServer
This approach allowed me to move faster and forget about migrations, for example.
But, but… Mario! Isn’t it risky?
Risk depends on context. My training sessions are short, and in the worst case scenario I would lose about 15 minutes of time and the students would have to restart an exercise if a GenServer fails during the training.
So, it’s a risk I’m consciously willing to take.
Talking about failures…
I can’t say I’m doing pure TDD, but I’m writing a lot of tests. Specially because I’m using Claude to generate some chunks of code for me (I’ll write later on which chunks of code Claude is writing for me).
It's really hard to use TDD with an LLM. These models generate huge chunks of code at once. Meanwhile, TDD is all about that incremental rhythm: one test, make it pass, and then tackle the next one. What I’m doing is writing tests for my GenServers, asking Claude to come up with extra tests I might have forgotten and then asking Claude to implement the functions that would make the tests pass.
I learned that tests are now way more important than they were before AI. When a LLM makes dozens of changes in your code, it’s impossible for you to guarantee that your code still does what it’s supposed to do. And I had Claude breaking my tests more times than I could count, specially when it tried to modify a lot of files at a time.
Decision: Using AI as copilot increases the need for automated tests. And the AI can help you writing your tests as well.
Design decisions
I acquired tailwindui a long time ago and I enjoy using its building blocks to create my applications. I can use it to make my product look nice without spending much time over-refining my design.
Of course, being a non-designer I also struggle with the overall layout. Even though I have beautiful blocks to work with I’m still pretty capable of messing the whole thing up when putting them together. So, sometimes I use Lovable to understand better ways to visualize how the components could go together.
Decision: Try to postpone having a database. Think about different ways to do that so you can learn more about your data before committing to a model structure.
Authentication mechanism
When I’m in a training session, I don’t want to have my students creating accounts and remembering passwords for an experience that will last for 2 or 3 days. I also don’t want to spend time fiddling with an authentication mechanism.
Now, I know some of you are thinking: “Hey Mario, it’s 2025! You can set up an authentication mechanism in a couple of minutes”. Maybe yes, maybe not. But I’m positive that having a full authentication mechanism would instantly add at least a bit of complexity to everything else I want to develop.
So my mechanism works this way:
You tell me your name, I save it to your session and you’re good to go. Unless you’re the trainer, of course. Then all you have to do is enter your name as SUPER_SECRET_PASSWORD and you’ll have access to advanced features.
Is it safe? No.
Is it good enough to use in a class with 20 people? Definitely yes.
Decision: Authentication comes in the last responsible moment. Think about it, work around it and maybe you’ll end up creating something innovative.
Deploy
I recently read the amazing book Simplicity by Dave Thomas, and there’s a lot of good ideas there. One I’m particularly fond of is: automate your deployment from day zero, so you can deploy often.
I did that using github workflows and my dedibox in Scaleway. Now I deploy by doing just a single:
git push origin deploy
And of course, the deploy occurs only if all my tests passes. Pretty basic stuff, I know. But doing that from day one allows me to deploy often and gather feedback quickly.
Decision: Create a hello world, deploy it and automate the entire deployment process before doing anything else.
Final Thoughts
A good pet project is a pet project you can quickly deploy and have other people to use it. In my case, as a trainer, the idea of creating a platform to simulate real life stuff during training sessions seems like a perfect fit.
Will I revisit some of these decisions? OF COURSE! That’s the entire idea behind each one of these decisions. One day I’ll have a proper authentication mechanism and a database, but when that day comes I’ll have a reason to implement these things.
As Jaqen from Game of Thrones would say:
What do we say to our need to implement authentication in our products? Not today.