In my 15 or so years of my career I've built multiple products, started my own VC backed startup (which ultimately failed because education is not a very good business), had numerous side projects reach a bunch of people and worked in large and small companies using various tech stacks.
Growing frustration
Over the years I've accumulated a lot of frustration with the industry:
- Artificial separation of the backend and frontend with the great big “REST API” being a separator. Often times you’d see the model being reimplemented twice, both on the frontend and backend. While the REST API is great for querying and filtering individual objects or lists of objects, it’s really not good at write operations that require touching several different objects, or god forbid, rolling back operations and transactions
- Constant reinvention and lack of standardization - here are some of the things I’ve seen almost every team do in a bespoke way
- Filtering, pagination or querying over the API
- Service discovery, service lifecycle management, communication and access patterns between services
- Parsing messages over websockets and websocket communication in general
- Long-running and background processes, especially in the frontend
- Insistence on one big API for everything instead of making specialized APIs for separate use cases.
- And some hot takes:
- To be honest I don’t really think JS is the best language/model for the frontend, especially with anything realtime or that requires background processes. I still think an actor model would fit much better there. We’re resorting to things like https://redux-saga.js.org to tackle those issues, but it still feels tacked on
- At the risk of sounding like an old grumpy guy I’ve been looking at older environments like FoxPro and how “easy” it is to build complex and data-heavy applications that map onto data types makes me feel we have regressed with the tooling available and have to jump through massive hurdles just to do simple applications
My experience with Elixir and Phoenix
I got approached to build an MVP for a project that was heavily built around real-time capabilities, and since I kept reading about Elixir/Phoenix I decided to dive in. It was not an easy learning experience - while the documentation is pretty good, it’s still hard to form a larger picture of how it all fits together. Often times I’d resort to going through the library code or looking at open source projects to figure out how to do things. Since then I’ve built more things and have gotten much more confident with the ecosystem.
Here are things that stood out to me:
- First thing I noticed was the OTP library - basically I’ve realized lots of things I’ve kept reinventing and seeing reinvented has already been solved 30 years ago and we as developers just didn’t bother to look back and learn from our predecessors. The Erlang/OTP/Elixir ecosystem comes with predefined building blocks you use to manage state, build state machines, manage asynchronous tasks and processes, communicate between components and more
- Quality of the BEAM tooling - I can’t help but think that a lot of expensive SaaS monitoring tools we use now are of lower quality and have lower introspection capabilities that’s available out of the box in the Erlang/Elixir ecosystem
- Service lifecycle management is front and center - defining a service/micro service architecture comes naturally and the tooling to manage it is very well thought out with various battle-tested approaches available and made explicit. Again, with no need to reinvent things.
- Ease of developing things with LiveView - as many have mentioned, this to me is the killer app of the ecosystem. It might be a hot take, and it took me a while to pin point this frustration of mine, but I’ve never understood why we insist on putting a REST API in front of everything - especially behind our own UI, which we have full control over and owe our users the best experience possible. I understand the benefits of standardization but it might not always be the best tool for the job. LiveView allows you to build highly interactive and real time web applications with basically no JavaScript involved and I’ve built things in a few days that would have taken me much longer with a more standard backend/frontend split approach. I’m not against REST APIs, but especially in cases where we’re building something where we’ll be the only consumer it might be an unnecessary constraint we place upon ourselves. LiveView still has some rough edges, but it’s improving rapidly
- Everything seems to be thought through and fits well together - Ecto and their Changesets fit well into Phoenix framework, LiveView is just another Elixir process, PubSub is a first class citizen, Tailwind is natively integrated, deployment works great with services like fly.io, most major email services are supported out of the box, and there doesn’t seem to be lots of random libraries around that break standard conventions. It makes it hard in the beginning, because to understand how something works you need a preexisting mental model in place, but it gets much easier after a while.
- Ecosystem is expanding rapidly - while still smaller than something like the node ecosystem, things are improving rapidly, with tooling like GenStage, LiveBook and Nx being added and improved upon constantly. At this point I’d be hard pressed to find a use case where I’d be limited by the Elixir
Drawbacks
- While the community reception seems to be great, job opportunities are still much smaller than with some larger ecosystems
- Some libraries and interfaces to major services are missing and you’ll have to make do with making your own wrappers or implementations
- While documentation on individual components is usually great it can be hard to wrap your head around how it should all fit together
Where I’m at now
I’m actively contracting on Elixir projects (examples being a real time bond issuing platform MVP and a podcast annotation SaaS) and building personal side projects. My most recent side-project https://inbox.video came together really quickly as most of the complex functionality like streaming uploads to S3 came supported out of the box and the Stripe library is world class. I’m working my way up in complexity and have started work on more complex projects like and automated website builder and a product analytics suite - which I wouldn’t have even attempted without a technology like this.
Honestly, I’ve never taken so long to onboard onto an ecosystem and that might be one of the biggest issues of the technology. Even with several projects behind me I still feel like I’m learning new things constantly and needing to figure things out. My opinion is that it has mostly to do with my point about everything being thought through and fitting together - I find this approach better than having a bunch of random libraries interacting together in ecosystems that keep reinventing themselves. The projects we’re building are complex and there’s no reason to dumb down the tooling we use to build them. The extra effort definitely pays off in the long run.
If you are on the fence and have some time to learn, I can personally recommend diving in and figuring things as you go. If it's still daunting but you still have MVPs in mind that need building, no matter how complex or diverse, feel free to reach out and we can agree on a IndieHackers discount :)
Great article! I'm currently learning Elixir and Phoenix and have the same problem: I can't fully see how everything fits together. I have an overview of how individual components work on Phoenix, but the whole thing is still a bit cloudy
Thanks for sharing. I’m very positive towards Elixir, though have to also share my interest in Svelte for front end interactivity.