3 ms·
I'm using django for more than 10 years, phoenix for like 4. I consider myself experienced in both frameworks. I wanted to write some blog post about my experie
by spapas82 4y ago
I'm using django for more than 10 years, phoenix for like 4. I consider myself experienced in both frameworks. I wanted to write some blog post about my experience with them, but never found the time.
In any case, Phoenix is a fine (niche) framework but can't really be compared to a masterpiece like Django:
* Phoenix, probably because of its influences from the ruby world is using some concept called "generators". Using the generator it will generate (sometimes a lot) source code files that will implement some functionality. For example, let's suppose you create a new schema (similar to the django model concept). You can use the generator so it will automagically create code for the schema file, its migratinons, some crud forms and even tests. This works fine until you need add another field to your schema, or you need to rename a field or just do a small mistake! Then you'll need to do some very error-prone and boring work. Compare this to the way that Django uses the Model to generate everything from that using class inheritance and composition, without the need to write any code. Also notice that the phoenix generators can't understand relations and you need to edit the schema and migration files by hand to properly add references.
* No auto-migraton support. That's that. If you add a field to a schema you need to edit the migrtion file yourself. Django automagically understands the changes and will generate the migration file.
* This generator thing unfortunately has influenced various other stuff from phoenix, like authentication (you use generators to create some kind of authentication code which then you need to edit). Again, compare this to the elegance of Django using the authentication backends. Also you use generators for presence, channels, whatever...
* The "ORM" (which is not really an ORM it's more or less a way to talk to the DB called ecto) is miles behind the Django ORM. It doesn't support any andvanced stuff, you need to do the joins yourself (i.e from(u in User), left_join: (a in Authority), on: a.id = u.authority_id, where: u.is_active == true. Compare that to User.objects.filter(is_active=True).select_related('authority').
* Also the ORM doesn't support most of the advanced stuff and you need to use an escape hatch called "fragment" that allows you to write raw SQL.
* Phoenix has no django admin. nuff said.
* The phoenix has some funny controller/view/template architecture (which I also think that was influenced from rails) that isn't very intuitive. The views are more or less useless and everything is like router -> controller -> template. Similar to urls -> views -> template in Django. But having the unnecessary views there adds another level of abstraction making everything more complexfor no reason.
* Things like template inheritance are not really possible in phoenix. You use a thing called layouts to re-use stuff. The Django template inheritance is much, much more powerful and simple to understand.
* Django is much more batteries included: Phoenix has more or less no authentication (beyond the generator generated one I mentioned before), no caching framework (you need to use some kind of extension), no pagination support (!), no permissions and various other things that you'll need to implement yourself or find some obscure library that has 3 years to be updated and doesn't suport the latest phoenix, which gets me to the next point:
* Phoenix needs a JS bundler for its javascript code. It used to use webpack and now uses esbuild. Still, they could just provide the proper compiled JS files and let us decide if we wanted to use any node-js stuff (which I avoid like hell).
* Re-using code among controllers is possible using plugs but definitely not as straightforward as extending class based views with mixins.
* The ecosystem is very very small. Most libraries/extensions are 1 person projects and most of these are from persons that tried phoenix for a project but moved on so they are unmaintained. I remember that there was the "default" pagination library in phoenix (scrivener) and it didn't support the latest phoenix for like 2 years? People had to use a fork instead.
* Better support and much easier updates. Because of the huge different in users, when you have any problem with django you're going to easily find answers on line. Also because Django is more mature and much more eyes look at its release candidates, it will be much easier to update to new versions. I've got apps that started from Django 1.6 and now are at 3.2.
* The documentation of phoenix is not bad but it can't be compared to the django docs.
Yes I know that until now I only told bad things about Phoenix but it's my experience and especially when trying to compare it with something definitely better. However I have used phoenix in a couple of specific projects and these were sucesfull. My opinion in that phoenix is not a general purpose framework but a niche one. When you have some specific requirements then yes phoenix would be a fine solution. These requirements are real-time updates using websockets. It's exactly the niche that Django (and python is general) is not good.
Phoenix, because of elixir (and erlang) is great on supporting small processes that can be used to implement quick real-time communication between clients and server so as to implement apps like chat servers, online games, broadcast communication server etc i.e when your http clients open a websocket and send/receive real-time updates to the server.
To enhance that even more, phoenix has a technology called Liveview that makes all this stuff even easier because it allows you to do client-side updates from the server side so as to keep JS to a bare minimum; instead of using react in your client side you keep all your app server side. This is a revelation and a much better way to work than using the client side JS framworks. This probably is the reason that Phoenix is loved so much more.
Please notice that I didn't compare Elixir/Erlang vs Python. Elixir can be used to create some stuff that can't be done in Python (i.e using processes to schedule or queue stuff etc) but these are not Phoenix/Django related stuff.
Sorry for the long comment, I guess I should have written the blog post ...
- yokaro 4y agoThere are many points in your comment that is a matter of preference... And with many of them I desagree... I used Django in the past and the "auto-migraton support" feature you are talking about is great but not perfect. It is even mentioned in the official documentation. I have been myself in situations where it created unwanted behavior. So I can understand the Elixir core team not wanting to bet on a feature that is neither perfect nor essential. > But having the unnecessary views there adds another level of abstraction making everything more complex for no reason. Hell no! Imagine how much more succinct and clear templates can be just because you moved some verbose logic into helpers defined in your views? I find that Phoenix encourages people, especially beginners, to adopt nice ways to organize their code. The generators you like them or not but you are not forced to use them. Personally I find that they boost productivity and are a very good learning tool. Finally I would say that Django did not become what it is in a day. Elixir/Phoenix is perhaps slowly but surely moving towards a future that I am impatiently awaiting.
- spapas82 4y agoI agree about some things being a matter of prefernece and also depending on the kind of stuff you are making. About the migrations; creating automigrations like django is a ton of work. It handles all trivial and most non-trivial cases perfectly. If you have some really complex stuff you can edit the migration file (it.s normal python). I don't like organiziging stuff into per-controller views, I usually need to re-use things and create helper views, or other modules having that functionality etc. So their usefulness is diminishing. About generators, I agree about the learning stuff (I actually mentioned that in my comment). About productivity... hm it depends on how useful they would be. As for your final comment? I definitely agree; Django is a behemoth framework with more than 15 years of development time and a really huge community of contributors. Phoenix is much smaller both in age and in community so it will definitely be less mature. But I agree that it moves towards the correct goal, especially if you focus on its excellent real-time features where it really shines!
- klohto 4y agoThank you for the insightful comment. I work with Elixir/Phoenix on a few of our projects, and while I do love both, all of these points ring true. Only thing I don't agree with is Ecto. I have found it more straightforward to work it and reason about, much because of the functional syntax of Elixir. But yes, I do hate generators. Adding auth to an existing project was a bad experience, since you need to do a diff to understand changes being added. Not only that, wanting to keep the code clean, removing redundant or completely unnecessary features requires you to understand how the whole thing works. On one hand, great, it's never a bad thing to know every single detail about your authentication. On the other, it's time-consuming, and maybe I would prefer the separate "blackbox" that I can opt-into with clear API which I can always dive into that doesn't mess directly with dev-written code.