Learning curve expectations - how-long does it typically take to become proficient in Elixir?

Wondering how-long it typically takes to become proficient in Elixir, Phoenix and other relevant areas. I am looking to set expectations for myself. After ~5 days into studying Elixir and Phoenix, there is still a lot of “magic” that I am trying to grapple with inside Pheonix; specifically, dealing with forms. Elixir seems mostly straightforward.

Coming from ~20 years of full-stack PHP / JS I can build web-apps pretty quick. My main gripe is long-term maintenance and managing complicated SPAs in both JS and PHP. This double work drives me crazy as I handle front and back as a one-man team. I could hack together a similar Phoenix-LiveView thing, but it seems futile as web socket connections on Apache / Nginx are more limited, which is why I assume LiveWire uses AJAX calls.

(I also cannot stand Laravel, but anyways…)

When you start stacking up the advantages it seems like Elixir has a strong lead over the traditional (PHP, Ruby and Python) web languages; I do not think they can be closed, but maybe I have not gone far enough into learning Elixir. The functional programming thing already makes it appear easier to maintain code over the long-term; so, I have basically been putting 10+ hours a day into learning Elixir, Phoenix, etc. over the past ~5 days. I believe Elixir is likely to be the future, or at least significantly improve my productivity.

My Questions, Searching for Perspectives:

  • Where (i.e., what type of apps) has Elixir been difficult to use for you?
  • What other programming languages complement Elixir very well? Why?
  • How long is a typical learning-curve in Elixir, let’s say to build an SPA?
  • Are there areas of Elixir where it is not so “elegant”, things it is clunky at?
  • Anything that helped you speed-up your learning of Elixir, Phoenix, etc.

Thank you, and sorry for the long post :stuck_out_tongue:

1 Like

I’d argue the first thing that strikes you coming into Elixir is: there’s no magic.

The only thing that exist, is functions processing argument, calling other functions in a predictable way.

Take the current Elixir’s de facto web stack. A competitor to Phoenix like Ash can say, hey I like your approach of user-facing tech, but I’m going to do something different in the data layer. Both can co-exist.

In that sense, I believe Elixir has no “Web Frameworks”, as in there’s not other app taking control your Mamuschka. The only thing we have are pre fabricated segments of the pipe that you can use to speed things up.

The “|>” operator, is not just a low level convenience, but a way of doing things.

Sorry if I didn’t answer your questions, just felt like venting out my love to this ecosystem.

1 Like

A common mistake that many people do – myself included – is trying to swallow a lot of theoretical material and thinking they won’t be able to get any job done before that. That’s nonsense and always was. Work very hard against that thought would be my first advice to you.

Learn the true advantages of Erlang and its BEAM VM – namely transparent parallelism and the ability to just kill a process when a small part of your system misbehaves, without taking down the whole system with it. If there’s something you have to learn by reading, that is it. You can ignore everything else; it will come to you as you go through the official tutorial (which I STRONGLY recommend!).

After you grok the parallel and fault-tolerant nature of Elixir / Erlang, just start doing something professional with it. Just dive in. If you truly get stuck, then come here to the forum. As long as you show that you’ve made effort and that you have some understanding, people here will help you.

Swim in the deep waters and you’ll learn to swim fast.


Nginx and Apache have the capability to use and upgrade connections to websocket without problems and a lot of us have deployed liveview apps with nginx as a reverse proxy.

The reason why LiveWire uses Ajax is that PHP doesn’t come with a websocket implementation and it would add one more library that needs to be installed and configured as a long running process complicating the deployment process (not even touching the fact that a crash could take the entire websocket server down, thanks BEAM for saving us from this kind of trouble), Elixir doesn’t have this problem and that makes it a choice with a lot more batteries included for these soft real time projects.

Number crunching and really performance sensitive problems aren’t that great, also FaaS, elixir doesn’t have the fastest booting runtime.

Rust, go, zig, c, c++, ocaml, etc, in general fast compiled languages with small and/or fast runtimes, if you can write NIFs easily with them even better.

This is as much an individual question as one of software engineering, the only honest answer is “it depends”.

Not getting into any kind of flamewar here, I like types, but it is a personal preference and I’ll leave it at that :wink:

Writing and reading a lot of code, there’s some awesome open source elixir codebases, clone them, run them locally, mess with things, figure out code patterns, if you see something interesting in some app think about how would you do that in Elixir (and try, writing code helps a lot) and so on.


I’m not going to be able to answer all of your questions, but I can maybe provide some insight. Last year this time I was basically where you are now; I’ve been a technology professional for a fair while and started what I think would be considered a substantial Elixir project.

It took me about three months to really find a good groove with Elixir. To put that into some context, I’m working solo with no mentoring aside from the occasional discussion in the forums here. When I started the project I did have a couple of the training courses under my belt (@pragdave’s excellent course… Elixir for Programmers and and very good courses from The Pragmatic Studio… https://pragmaticstudio.com/) I also had a fairly long period of learning “big idea” stuff and watching things evolve here; while that certainly helped, the goal with that was not to learn about how to develop in Elixir as much as it was to decide if the stack, ecosystem, community, etc. was a reasonable choice to use for a large project given the time commitment. As @dimitarvp points out though, for learning things that’s no substitute to diving into a decently realistic project of your own where you’re solving the problems with much less safety net.

That initial 3 month learning curve included Elixir proper, writing tests, documentation, and Ecto and did include a fair amount of “off-the-beaten-path” work which a more typical project could probably avoid. Notably it did not include Phoenix. I have found the most commonly used frameworks and libraries to be well conceived and well coded. I especially have a sweet spot for Ecto; it didn’t take long to learn at all… but I do a lot of database work so it was very naturally to fit into my preexisting knowledge.

After the initial 3 months I’d say my experience is that I spend much more time up front figuring out how, say, a module should be designed like or getting a good clean set of functions in shape etc than I have taken with other development projects using other languages. On the flip side, I’ve found that when I need to refactor for whatever reason that the refactoring tends to move much more quickly in my Elixir project than in my other previous projects. I can’t say that’s the common experience, especially with those in here with deeper experience both in Elixir and development than me, but that’s how it’s been working out for me thus far.

At the beginning of this month, the my project started with front-end stuff… specifically the Phoenix 1.7 RC’s and LiveView. It’s taken me until just today to get a good looking multi-step form done from beginning to end. Some context: while I have almost 30 years of professional technology experience, none of that can be said to be in web development… I’m an “enterprise” guy… (which probably now has a lot of people wondering why I’m here :slight_smile:) … I did step into a PHP project back in 2007, but even then the actual front end was done in Adobe Flex (I actually liked ActionScript). I also have a fair amount of Qt experience… but not web. In this month I’ve been able to get a fair number of custom components done, an elementary sense of how each of the events proceed and dealing with certain long-running processes (handle_info kinda stuff), and standing up different web sites for my admin and customer access from the same project. Still a long way to go and I’m not going to say my code is clean right now… but it works as my requirements require. That month did include getting up to speed with basic web technologies (HTML 5 didn’t exist last time I did any web work and CSS has changed a lot, so I’ve been learning Tailwind, too.).

I’d say the two biggest issue areas I’ve run into are related to tooling and Phoenix.

The tooling issues are around Dialyzer and some of the editor tooling. Dialyzer, looking in from the outside, seems like a perfectly sensible thing to want to use… and then you use it… oh dear. Most of the problem I have with Dialyzer is that often times when it tells you something is wrong it tells you in some of the most cryptic ways and then when you do find the issue it’s either minor or with the description of what it should find (the typespec) rather than the code itself. To be fair, I can’t recall a time that it’s actually been wrong, except maybe when it hasn’t found an actual issue. It’s just time and effort to get through a Dialyzer run isn’t always as productive as you’d hope it would be and also there’s a fair number of people that just don’t use it. The editor issue is primarily focused on ElixirLS. Here I’ve only got two real issues: 1) some of the sanity checking it does is done through Dialyzer (see previous discussion above); and 2) for me it can be pretty slow. Not getting code suggestions, docs, etc. nearly as timely as I’d like. Some of this may be certain times where the code needs to be reanalyzed in the background and such and when it does work for me it works well. To be fair to that team, I believe their focus is mostly on VS Code and I use Sublime Text 4; so I may be getting some impedance mis-match there. I don’t know… overall I think the whole area could use a “rust analyzer” kind of moment (if you know what I’m talking about) vs. a more evolutionary approach. All of the tooling stuff is in the annoyance department and not fatal flaws.

My biggest issue with Phoenix right now is not atypical of my issue with a lot of larger frameworks, including those outside of the Elixir world: a lot of magic going on behind the scenes to make it a tool worth using. When black boxes work well, there’s little need to see what’s inside; but when things don’t work finding out why can be more of a challenge than it might be when delegating less heavy lifting to third parties. I’ve made matters worse for myself in that 1) I’m learning phoenix and web dev stuff, 2) I’m using pre-release software. This means for me it’s both more difficult to know why something is going wrong and it’s difficult to know if it’s because I’ve done something wrong (the most likely) or if I’ve hit a bug. Having said that, again, this is annoyance more than serious issue and as I progress I’m beginning to see how I can leverage Phoenix to save me a fair amount of time over the course of the project. Ultimately, I think a professional web developer will fare much better with picking up Phoenix than I have so far.

Insofar as I have listed issues which are less about my state of learning and are real in the ecosystem, I do expect them to be fixed. I deeply appreciate that the core language has, by design, reached a point of substantial stability and that the new/shiny stuff is mostly happening in libraries and such; that alone protects a fair amount of investment. It also means more time to fix the circumstantial issues I’ve discussed.

My expectation, should I need high performance code, is that I’d use Elixir with Rust. Rust seems a natural fit, especially if you’re going to have to go down the NIF path. Seems like it would be hard to not just default to Rust unless there was a compelling reason to not use it.

Ultimately, I have not been disappointed with my choice of Erlang/Elixir based technologies for my project. This community in particular has been especially helpful in getting through a lot of the roadblocks I’ve faced… not because I’ve asked a whole lot of questions, but because most of my questions had already been answered here for me to find.

Hope that helps some.


There is one part You did not mention… it’s the OTP library.

The document is for Erlang, but applies (with syntax change) to Elixir.

You don’t need to learn it to use Phoenix, but You should :slight_smile:

For Elixir, the Enum module is a must. You need to be fluent with map, reduce, filter.

For OTP, You need to know what is a GenServer, a DynamicSupervisor, a Supervisor, and the supervision tree. It’s nice to know about link and monitor, and how the fallback system work.

You need to know Ecto, and how changeset works if You want to access the database.

And then Phoenix. It’s better if You know how macro works to understand some Phoenix magic. It’s easier if You know Rails, as they share some concepts.

Elixir, and Erlang are good when interfacing with other languages.

Ruby and Python can use erlport
Rust can use rustler
Zig can use ziggler I think… not sure, I did not try
And for the rest You can use port, or direct call

You might find deployment is a bit complicated the first time, but once You did it, it becomes trivial.

You should not dismiss websocket, it’s one of the cool stuff of the stack. It has presence support, and it works between multiple nodes. There is a phoenix,js npm package to use with SPA.

You can build an API easily, use Phoenix Token for token authentication, and use websocket for realtime communication with the frontend. You can even add GraphQL with Absinthe + Dataloader, to build flexible API.

Or You could use liveview, to avoid JS framework.