4 minute read

I created Enig, a tool for simple estimation for distributed teams. Its a shared session where you can agree on a scope of a given task, without any overhead.

A screenshot of the website Enig, showing four votes and a voting mechanism
A screenshot of Enig

Try it at enig.lamdera.app

This post describes the why, what and how the app was created.

Why?

When using traditional story point estimation tools I have found they are not fitting for the use case.

They are often not very smooth, ridden with ads or overly complex. I wanted to make sessions easy to setup, maintain and join. Everyone are assumed to be in the same team, so no “host” mechanism or similar is needed (for now at least). No login is required, as that increases the threshold for everyone.

I wanted to try to make a simple tool, that is also easy to maintain and serve for years to come.

What?

So what did I need to build this?

The base framework is Elm via the awesome Lamdera. Lamdera lets me create full-stack reliable apps with a synced backend and client-to-client push communication.

Elm is a strict functional language for the web. It guarantees no runtime exceptions at the cost of: ‘You have to handle everything that could go wrong.’. Stuff that can go wrong is usually every webrequest ever. Thats where lamdera comes in and says: “I guarantee the networking layer and that the types are correct when the elm frontend receives them.”. This means enjoyable programming with a tight feedback loop!

I built the user interface with the also cool mdgriffith/elm-ui package. What elm-ui gives me is: No CSS, no HTML. Type-safe elements that can never be misconfigured with cool defaults! There is Zero html and Zero css in the Enig code. Try elm-ui yourself, its a delight when it really works.

And thats the stack.

The entire app consists of three files. Frontend.elm, Backend.elm and Types.elm.

How?

So lamdera ensures that everything is wired up, I dont need to think about wiring at all. The Types.elm file determines the contract between frontend and backend, and updating this file forces me to implement handling in frontend and backend.

I started with a simple model of a “Room” which is a session for 1 or more users under a common room name. A room had a list of votes. Each user may only have one vote.

Whenever a user initiates their vote, a message is sent using SendToBackend (ChangedVote RoomId Vote) which has to be handled by the backend. The backend then finds the correct room, updates the vote, and broadcasts back to all connected clients that the votes are changed.

Each client is automatically synced with this new change. If any client is disconnected or similar the state will still update when they are back online. Very cool!

Whats next?

Lets see if this is useful and if there is any user feedback. If there is anything you would like me to add feel free to message me or create an issue at the repo.

You can check out the code at: https://github.com/Strepto/enig

This is not my dayjob and not my most proficient stack, but I’m pretty satisfied with the result! I think i’ll move over to other smaller apps as this one feels quite complete as it stands right now.


Try Enig at enig.lamdera.app

Thanks for reading!

// Nils Henrik