Skip to content(if available)orjump to list(if available)

Why I Chose Elixir Phoenix over Rails, Laravel, and Next.js

mati365

I implemented CKEditor integrations for Rails, Livewire, Phoenix, and React. I think the best developer experience was with Phoenix - at every step I was surprised by how well thought-out the framework is and how easy it is to build integrations for it. I definitely can’t say the same about Rails or, especially, React with the awful Next.js. For anyone curious: https://github.com/Mati365/ckeditor5-phoenix

As for Livewire - it feels like a simplified copy of Phoenix. In my opinion, it’s less advanced and less intuitive. For example, Livewire components don’t support slots, while Phoenix components handle them without any issues. Slots are critical for clean component composition - without them, you end up with messy, repetitive templates and a lot of unnecessary logic in the components themselves.

When it comes to Next.js, constant router changes and questionable decisions have become a daily routine. There’s no point integrating with something that gets rewritten every week and can’t be trusted to stay stable.

dominicrose

PHP (Laravel) + JQuery still works for me in 2025, but I would never use Livewire.

Using Node.js would hurt productivity but it's more powerful if needed. It may be needed because it has async/await and it has socket.io. It's also possible to use Typescript.

Next.js can be useful if you need everything (good SEO + highly interactive) but let's be honest how many websites need good SEO and websockets? LinkedIn maybe.

mati365

I'm not so sure Next.js is as SEO-friendly as people claim. The JavaScript bundles are pretty heavy, and the page still needs to hydrate before it becomes fully interactive. There are attempts to speed this up with React Server Components, but the developer experience there is already worse than with Phoenix components.

Next.js server performance isn’t great either - honestly, it’s pretty bad. Pages don’t feel that fast for users despite all the tricks and optimizations. In my opinion, metrics like LCP and others are much easier to optimize in older, more traditional frameworks. Unless you’re building a full-blown web application, a classic web page will almost always be faster and simpler to deliver without all the Next.js complexity.

tracker1

I think if you're going to push closer to the server in a client+server app, I'd probably look towards either HTMX integration options with a preferred backend (there's some cool C# integrations from Jetbrains as an example) or Astro over Next.js ...

That said, I'm not necessarily a big fan of mixed environments since IMO most web apps can be mostly client side and most websites can be mostly server driven. Either is simpler than the mingling tends to get. That's just my take though.

jarek83

I wonder what made it hard for you in Rails.

sodapopcan

As a fan of both, the LiveView DX is simpler than Hotwire's (though of course there are trade-offs both ways). With Hotwire you have the think about frames whereas LiveView is more like React where you just change the state and the appropriate diff is patched in without having to think about much else. This is not to say that Hotwire's frames are complex, LiveView is just that much simpler in that regard.

ramon156

I want to give both of these a try, especially if you say react+next.js is awful. You'd think TS-TS would be well thought out

tracker1

If you want to mix server with React and TS, then take a look at Astro or HTMX.

Tade0

I'm curious about your experience with Rails. What specifically caused issues?

mati365

The main issues were related to how JavaScript is integrated and distributed within Rails. In older versions, you have to deal with Sprockets and dependency bundling, which is tricky if you want your integration to work across a wide range of Rails versions.

In newer versions, import maps are recommended instead. The problem is that import maps enforce ESM, while Sprockets (as far as I know) doesn’t support ESM at all. On top of that, there are compatibility issues with Turbo links, various form libraries, and the limited extensibility of the import map library itself - adding extra dependencies is just painful.

Installing CKEditor wasn’t straightforward either, so I ended up creating a small DSL to simplify it. But then came another challenge: providing support for custom plugins in a way that would work with every Rails version, even without a bundler.

All of this is made even harder by the fact that CKEditor is distributed in both cloud and NPM versions, which complicates integration paths further.

In contrast, Phoenix makes things much simpler. From what I remember, the standard setup uses esbuild, which automatically pulls NPM dependencies from the deps directory - the same place where Elixir libraries are installed. This means you can distribute a package that includes both the Elixir and NPM parts of the editor, without having to manually modify package.json or worry about dependency conflicts.

danmaz74

It looks like a lot of these issues are due to the fact that Rails has been around for a long time, has lots of versions, and you wanted to support many versions (Which is commendable, by the way). If you only had to support the latest Rails version, how much harder would it have been than doing the same for Phoenix?

xutopia

I love how this article reads more like the individual ignores features and capabilities of other frameworks to then state that the framework he chose is better.

Rails has everything he mentions as an advantage of Phoenix. He's also implying that Rails does not use web sockets to communicate with frontend which is not only wrong it should be evidently wrong to anyone who built a Rails app in the last 3 years.

That's not to say that Phoenix and LiveView aren't phenomenal tools, they are! However what's keeping me in the Rails world is Hotwire Native. I truly feel like a one man army building mobile and web apps in a quick turnaround time.

garbthetill

Ive only used ruby a handful of times, so my comment might be ignorant. But other than community , what does ruby and ror do better than say elixir & phx, i feel like the latter is leagues ahead simply because nothing can compare to the beam platform for soft real time systems, you have fault tolerance, nifs, actor model , you can have millions of processes running at the same time for cheap, easy to reason about concurrency , fp makes code concise imo, otp, the beam gc doesnt stop the world etc I just think on paper phx is superior thanks to the beam platform

That being said use what you like and hotwire native sounds cool will give it a try. I also think the author of the blog shouldve went a bit deeper with his points

theappsecguy

The gem ecosystem and hiring pool is much better. Otherwise, as raw tech it's worse

nomilk

Yup. the rails 7 demo showed websockets back in Dec 2021:

https://www.youtube.com/watch?v=mpWFrUwAN88&t=25m46s

gregors

The problem is the websocket implementation (last time I tested it) sucked. I'm assuming even now if you're doing non-trivial websockets you need to use the node or golang implementation.

aantix

You can swap out the ActionCable backend with different providers.

Redis, postgres. I think there's a couple of commercial offerings.

solid_cable is a database polling mechanism which can also be swapped in.

akarshc

That’s a fair take, rails with hotwire is genuinely powerful, especially with hotwire native. but the post wasn’t about claiming phoenix is better, it’s about how liveview’s model (server driven state, process isolation, lightweight channels) fit a specific use case. both ecosystems solve similar problems differently, rails leans on conventions and progressive enhancement, while phoenix leans on concurrency and fault tolerance from the beam. at the end of the day, it’s less about which is superior and more about which workflow clicks better for what you’re building.

mountainriver

In the era of vibe coding just use the fastest servers. I wrote my last api in Rust and it wasn't any harder than anything else, it's wicked fast and stable.

After doing that, it seems a lot of the higher level languages will go away soonish

jherdman

> But I still needed background jobs, real-time updates, and two-way communication that just works. Those things are possible in Rails and Laravel, but they take a bit more effort to set up.

I'm pretty sure this isn't true at all with Rails. Out of the box you get Solid Queue (jobs), and Solid Cable (real time messaging).

nop_slide

Yeah def odd, I'm a recent rails convert and SolidQueue is dead simple and is setup out of the box.

When paired with https://github.com/akodkod/solid-queue-dashboard you get a nice overview.

jamiecurle

I think what the blog post is getting is OTP and the mystical/but not mystical GenServer / Supervisor/ distributed pattern. It's baked right in there as a core part of the Erlang VM. I think the post glances over the fact that in rails land solid queue may be right there to use (I've not really used rails in over 10 years).

Thing is with Elixir though, yes the tools are right there, but you do have to take time to understand them. I've been on and off with Elixir since 2016 and I'm currently wrapping up on a fairly complex elixir project with zero UI. (connecting Shopify GraphQL to a series of 3rd party fulfilment providers who use SFTP (gross). So yes, GenServer, Supervisor etc are all right there as first class citizens, but whilst they are relatively simple to start using, you can end up with some horrifically structured code that would have been much better written without the distributed stuff.

Personally, I prefer Django. Been using it since 2006 and as a person who started off in design but ended up as an engineer, nothing beats Django's template engine (braces for incoming). Django isn't perfect but nothing is. When I have to get something done quick and there's UI work for me to do, I go to Django. When performance or no UI, I go elixir. If someone else is doing the UI, I go phoenix.

akarshc

All the things are possible in rails as well. it is a beautiful framework, but it is so much easier to use with phoenix. Do try it out

gregors

As someone who did Rails professionally for a very long time, Phoenix/Elixir is now my default stack.

Possibly the one thing that Rails still does better is generating quick throw away CRUD apps with their generators. Rails is still pretty much flawless in that regard. That beings said, when things mature and complexity grows Phoenix/Elixir is definitely the better all around tool.

nasmorn

I think LLM have really closed that gap. Quick throwaway stuff can be generated in a couple of minutes. But phoenix gives me back all the control in cases I care.

x0x0

why / what do you find works better?

dimitrisnl

The post is mostly about Phoenix LiveView, while the title makes it about the framework.

To be honest one of the reasons I don't like Phoenix is that even if I opt-out of LV in the generators, I still get a lot of LV code.

alberth

After Elixir announcing being "feature complete" a few years ago, and then Phoenix going down the LiveView path for quite sometime ... I feel like the Phoenix/Elixir stack became less exciting to me.

Hope to be wrong though. Erlang based systems are really interesting and under appreciated.

toast0

> I feel like the Phoenix/Elixir stack became less exciting to me.

Isn't that what's supposed to happen? It's not really fun to build on top of an exciting platform. Boring means if I build it today, it's likely to continue working for a long time. I've always got more to do than time to do it, so having to rebuild everything all the time because of underlying excitement is not by idea of a good time.

null

[deleted]

recroad

Can you explain more? What became less exciting and why exactly?

alberth

It just felt like momentum slowed and/or there was less PR about Elixir/Phoenix.

But I could be completely wrong (or have the wrong perception).

Note: not at all suggesting hardwork/progress isn't being made.

bargainbin

In your defence, the choice of wording is confusing and that particular announcement did have a sense of “game over”ness to it.

But the intent was to say that Elixir as it stands from a paradigm perspective is done, but the existing features and runtime will still be improved.

Which as someone with many years in .NET, I can appreciate. I showed a friend who used C# since the first beta, who’s been hands off for over half a decade now, some modern C# code, and he could not believe what he was seeing.

Much like I can’t believe what I’m seeing when I review a C# code base and have no idea what flavour du jour the developers decided to write it with and how I have to frame the program in my mind to understand it.

Compared to Elixir, which just looks like Elixir has always looked, and does what you expect.

bluehatbrit

The pace of new things coming to the ecosystem hasn't slowed at all, but it's happening beyond the language itself now.

Just look at projects like Nx, LiveBook, Explorer, Flame, and Nerves. All are making big steps forward and releasing new and interesting things.

As someone who uses the stack daily this is really wonderful. In the elixir world you just don't really have the problem where two tools don't work well together because they're built around very different versions of the language and runtime. I can pick up any elixir based tool and knowledge I can slot it into my tool chain or project and it'll just work.

To me this is even more exciting because it suggests a stable foundation, and makes it easy to adopt new developments. But I appreciate those projects aren't discussed as much on HN.

dsiegel2275

I've been developing full-time in Elixir / Phoenix for the last 6 years. I can assure you, momentum in the ecosystem has not slowed at all since the language was declared to be "feature complete".

riffraff

hasn't elixir kept innovating? The whole static typing/inference system seems pretty cool and keeps improving.

edit: eh, I just went to check and they just has a release today :D

https://elixir-lang.org/blog/2025/10/16/elixir-v1-19-0-relea...

cantor_S_drug

For those who want to experience the strength of Elixir, they should watch all videos of Saša Jurić on Elixir.

duckydude20

iirc he wrote elixir in action. also. really good.

samjowen

Indeed, it's a masterclass in technical writing. It's the best programming book I have read.

schultzer

A lot of people tend to flag Elixir for its size and rightfully so, but the community is trying to punch above it’s weight with SOTA libraries. As an old developer once told me: less is more. https://github.com/elixir-dbvisor/sql

nasmorn

OTOH JS is too big for my taste. Everything has 10 implementations with no consensus about doing things. So everyone chooses their own horrible menu. Like an American super market. Or you go full chain restaurant with whatever Vercel pushes currently

magdyks

My biggest problem with Elixir is the lack of support for 3rd-party libraries and the small community. I love the idea of it, but every time I try to ship a real project in LiveView, I'm left feeling like the community is not that mature. Maybe coming from a Go backend React frontend stack, that might be the case, but maybe for quick CRUD apps, it's great.

dpflan

Elixir is pretty "nifty", and has Rails feels. I have worked on and seen its performance compared to scaled up Rails application. The BEAM / OTP is a very cool system to program on top of. I think it would be a great underlying system to develop a consciousness for AI systems with its concurrency paradigms and message passing, node connecting, other builtins. I'm not sure if the AI/ML focused Elixir projects like Nx have really taken off, but again, an Elixir based system that accepts numerous connections, passes messages around like exciting synaptic communications between functions... it just seems cool, maybe just on paper...

lab14

What do you mean "consciousness for AI systems"?

dpflan

When you consider the message passing paradigm, I can envision how that simulates neuro-chemical communication between neurons (now here being functions that do things). So there is a design for communication between functions, then there are memory storage and information retrieval parts of the system, short-term RAM, long-term HD/SSD, databases, cache-systems, where relevant information can be and become manipulated. Long and short running processes, acceptance of fail-fast and that communications can fail and that's just part of software system life (I assume also a similar idea in the human brain, don't you find yourself forgetting something you were just thinking about?). There is then the external part of the system, accepting inputs from the outside.

exabrial

The Elixir live view model to me look like one of the only sane programming models for modern web development right now... Otherwise your best choice still remains to be server side rendering.

dismalaf

> Otherwise your best choice still remains to be server side rendering.

?? Phoenix Live View IS server side rendering...

exabrial

Yes. I wasn't implying live views are not this, I was trying to say react, vue, angular, svelte, next.js, solid, preact, alpine.js, ember, backbone, lit, mithril, stimulus, knockout, aurelia, polymer, riot, inferno, marko, dojo have a terrible programming model and anything with server side templates is a vast improvement.

azundo

I think they more specifically mean server side rendering of react components vs an SPA.

rkangel

Oban is great, but for most cases you don't need it. In languages with a less good concurrency model we are used to needing some form of library or system to manage "background jobs", but in Elixir you can just spin up some GenServers under a supervisor to do work. Start there and only use Oban if there's some form of consistency/resumability guarantee that you need.

cultofmetatron

> Oban is great, but for most cases you don't need it.

7 years in on an elixir startup that has well over a thousand active paid accounts using our system every day to run critical businesses. I have to politely disagree.

USE OBAN from day one for any kind of background jobs. do not trust genservers. they lose their state if a pod goes. There's no retry logic built in.

> Start there and only use Oban if there's some form of consistency/resumability guarantee that you need.

oban is easy enough to integrate. it takes like 10 min of your time and you get a LOT out of the box. use genservers if you're running ephemeral servers but if you are creating background tasks, absolutely use oban for anything you plan to put on production.

Oban is such an easy value proposition to justify. consider it as important to learn as core phoenix

parthdesai

With GenServers, what happens if you pod/machine crashes? You lose all the unprocessed jobs. Oban gives you safe retries, and guarantees consistency. If you're using a relational DB, I would infact suggest to start with Oban, and then take a look at the jobs and see if you are okay with losing jobs and move to GenServers.

itbeho

I haven't found Oban difficult to work with and it has the added benefit of ensuring your jobs are run only once. There is also the cron functionality that I find really useful for scheduling.