Hacker News new | past | comments | ask | show | jobs | submit login
Phoenix 1.7 for Elixir: Edit a Form in a Modal (appsignal.com)
157 points by amalinovic on Sept 12, 2023 | hide | past | favorite | 115 comments



I'm a big Elixir fan, but unfortunately Phoenix is starting to suffer from an overuse of LiveView.

LiveView is great, but it's sort of becoming the default way to render everything--even static pages! TFA is a good example of this, where they use a Live view to render...a static list of icons.

The problem with this is twofold:

- LiveView is not free. It seriously affects people with unstable connections, for example. It creates a new class of silent bug at the client/server interface, where the client just sees "broken" pages (instead of 500 pages).

- It adds cognitive overhead. We bloody know how to do server side rendering. We've been doing it for 30 years (!). It's a good model. Don't make me learn something else, please.

Phoenix, which is a jewel of a framework, is risking becoming an "SPA-like" framework, with a new paradigm, and a whole lot of overhead to learn, footguns you've never encountered before, bizarre failure modes, etc.

I mean, TFA even has a section where they talk abut an obscure but that "...is a doozy, so I will save you some hours of debugging."

We don't need this!

One of the things that made Phonix/Elixir great is how simple and opinionated the core team has been. Conventions are Very Strong, but not magic. Unfortunately, LiveView is so cool (it really is!) that no conventions were built around it and it's now used for everything.

IMHO LiveView should be used with a very clear heuristic:

- If the page is static, render a static page.

- If the page is dynamic, and the content changes depending on calculations happening server side, use LiveView. It truly shines here.

- If the page is dynamic, and the content changes depending on actions performed by the client, use JS.


I see this same issue with htmx and other takes on SSR.. just because you can dynamically update the HTML doesn't mean you should make EVERYTHING dynamic. It's okay to have normal page transitions. It's okay to do something dynamic. It's okay to to toss a little plain ol' JavaScript in there if it's simple.


I recently started to only use liveviews for any page. Yes, I could do a simple controller/template combo, but then after some time comes the feature request for some interactivity, and I have to convert the page to LV manually. Or something like the global navbar needs some dynamic thing, and here you go: either embed a LV in the static page or... do nothing since all pages are LV to begin with. The overhead is pretty minimal IMO, a simple LV that does nothing is a few lines of module code, not much more than a controller route. And by standardizing this (no more deadviews), pipelines/plugs can be simplified, and live_session for seamless navigation becomes much better. Phoenix Deadviews render within a few MS, but still a live_navigate is snappier.


I agree with the GP, but I've definitely been staring down the barrel of this paradigm as well.


I strongly agree with you.

I'm fairly involved in Elixir, so I run a risk of catching some frustration for agreeing with you here.

I get why they are going the direction they are, but I think it comes at increased complexity for beginners (that don't want to use LiveView). For example, Phoenix components (which are usable in static server-rendered controllers) live in phoenix_live_view package.

All of that said, Elixir / Phoenix is the best development experience I've ever had and I have no plans to stop using it.


It's like that piece in Fantasia where the apprentice (Mickey) gains the wizard's powers, then loses control as all hell breaks loose. It's a powerful new tool, but there's a time and a place for it, and I believe that the tendency towards LiveView-everywhere should be balanced against pure practicality. I look forward to a future in which the boundaries of the paradigm are more well-understood, and the models of when and how to use these tools are more fleshed-out.

Also, I agree with your heuristics. It is untenable to make a round trip to the server for things that can be done purely on the client side. Alpine.js is great for managing purely client-side stuff IMO (as are LV hooks, although I haven't used them too often), but they don't really mix well, and Alpine seems to have fallen out of favor lately with the Phoenix crowd as the complexity of people's projects starts to reveal the cracks in the paradigm.

To add to your heuristics, the `phx-loading` attribute should be used when possible to notify the user that 1) yes, you made the action, and 2) we're still waiting for a response.


I kind of agree with you, and LiveView is not even 1.0 yet (it should have been before the whole components thing IMHO).

I also think they kind of jump the shark with the core_components.ex tied to Tailwind.


100% agree, and it's scary.

By the way, did something like activeadmin pop up?


What is "TFA", please?


Internet-shorthand for The Featured* Article--the webpage/blog post/etc being linked.

Sort of like OP, GP, etc.


"the fucking article" - the classic acronym RTFM (read the fucking manual) spawned the variant RTFA in the social news era, and then the article itself became TFA by extension.


Ever since I read a book on what Erlang/OTP and Elixir do, I question why we put up with kubernetes/openshift and microservices at all. Even phoenix seems to do what SPA/SSR frameworks want to push atm. Does this stack really put everything under the sun to shame?


> Does this stack really put everything under the sun to shame?

Yes. I'm a .NET guy by trade and I've poked around Elixir/Phoenix a bit. I wish this stack (and its concepts) would gain some popularity in the enterprise so we could get rid of microservices and SPAs entirely. 99% of companies don't need Microservices, they solve problems they don't have at costs they shouldn't have to pay (velocity, complexity, etc.) SPAs could go away for most LOB apps with Phoenix Live, Blazor (.NET), or even just classic server-side web apps + Htmx.


Just upvoting this isn't enough. I work in a large .NET shop. I only wish there was just the option of building admin or LOB apps with any of the three you listed above.

Sure, there's some consistency in the tech stack, but I do not need a full-blown TypeScript/React SPA any time I just need a page with a form.


What is "LOB", please?


"Line of Business"


In house apps.


Line of business, I think


Yes. Same. Microservices are a horrible solution to problems better solved by different means for most cases I've seen.

Ever looked up Orleans? https://learn.microsoft.com/en-us/dotnet/orleans/

Actor model for .NET

There's also AKKA.NET


Not everything of course but for the sort of network-based soft low latency uses web apps are built around yes pretty much. Even within its domain it has some weaknesses but their contours and mitigations are well understood. OTP is venerable and proven.

If you're ever looking at microservices as possibly a good idea you should definitely consider "can I just do this in erlang." Usually the answer is "yes, but no, because of company politics" and those hurt a lot once you know what you're giving up.


Out of interest, what book was that?

I've had a brief look into the ecosystem, but I found it quite hard for me to understand how a multinode Erlang cluster is setup.


I've read a few and sat through a few video courses. The book that made the OTP part really click and appreciate why and how was Elixir in Action [0]. There is a new edition in MEAP at the moment too.

[0] - https://www.manning.com/books/elixir-in-action-third-edition


Programming Elixir by Dave Thomas. It was very digestable for me.


k8s is meant for frameworks and runtimes, like Rails, that don’t have any real concepts of processes or clustering.

I think of Elixir as a way to get full control of the stack in one runtime. It has process management and clustering built right in, which is kind of redundant with everything k8s offers. It gives you so much control over so many things with one runtime and language.

Contrast that to a runtime like Ruby/Rails where it’s “run a server process and don’t attempt anything outside of that” — k8s can actually be helpful for process management, clustering, and service discovery because doing so in Ruby would be a huge effort that requires cobbling the Ruby, Linux, and k8s things together that you just don’t have to do in Elixir.


> Does this stack really put everything under the sun to shame?

I feel like protobufs are an improvement to Erlang serialization for talking to possibly older versions of things.


How does Erlang/OTP handle auto-scalup and scale-down ? k8s offers that.


It doesn't natively, but you could have (in AWS) an auto-scaling group based on CPU load where new nodes automatically join the cluster.


it does[1].

- A phoenix application basically can be seen as a "microlith": monolithic codebase (even with umbrella setups!) and during runtime there a lots of independent processes that scale over clusters of VMs, where partial failure doesn't neccessarily affect the rest. So no truly independent deployments of microservices, but most advantages of the pattern, without HTTP-API overheads or similar, since sending messages between processes is a natural thing to do anyways.

- Liveview extends that by connecting a client with the VM via websocket, where there is only a minor difference between receiving a message from another server process or from the client (handle_info vs handle_event). The data/state lives completely in the users' backend process, so much less cognitive overhead about getting data into the client, you actually don't even think about this topic. Also no JS blobs that get bigger with increasing amounts of pages/components or clever splitting + latency compensation of prefetching, and the SSR performance is spectacular, and also free (see the complexity of ReactServerComponents) and no thinking about the whole topic while doing LV.

- under demanding pressure, the VM behaves optimal for a web app actually. Every LV is its own process on the server, every "thing" ultimately lives in some process, and its all supervised by other dedicated processes that do automatic restarts/... in case of failure, sometimes called "self-healing". Erlang was the original system actually achieving the nine-nies of uptime. Garbage collection is also on a per-process level, not a global stop-the-world thing, with short-lived processes cleaned right away without the local GC kicking in. And the VM itself does aggressive preemptive scheduling. This translates into: quick http responses stay quick even under load, but long-running jobs run even longer when there is pressure - exactly what you want: not blocking visitors' experience with crunching jobs.

- the database story is exceptionally great, you have schemas and separate functions to do stuff with data (validations/...), not a coupled thing like ActiveRecord models - I can have different changesets/rules per usecase on the same schema easily. Can also be used for casting JSON responses, and supports embedding document-like structures (with schema/...) into postgres natively.

- many problems you would reach out for external services to solve have native built-in equivalents. IE you don't need Redis, since there is the built-in (D)ETS. which also is objectively better than redis for caching needs, since there is no serialization overhead between service boundaries, and native language structs are used for keys/values, not just strings, and it can be queried/matched with full power. When you know your full Elixir toolbox, your app becomes much simpler on the highlevel (architecture/infrastructure) and more convenient on the lower (code) levels.

- Everything[2] is packaged up (i believe) in an industry-leading level of polish and quality, from exhaustive docs, awesome testing tools built-in (ExUnit for liveviews is dramatically better to use than something like cypress and getting app configs right for testing modes and you have the fullstack integration testing level by default easily.

- the data processing/ML story is generally great and is quickly catching up to python levels, and the unique capabilities of the VM itself unlock tools like Broadway to build data pipelines to feed into things like ML models. Speaking of, some algorithms like NN have great native libs now, there is a adhoc integration with huggingface (bumblebee), and last but not least some things like evolutionary algorithms are great to design with OTP constructs.

- the language itself is as powerful as a lisp in practice, the only noticable exception being its not homoiconic so you need quote/unqote for macros and AST stuff, but also there are less brackets. But everything you see is a macro ultimately, even defmacro is a macro. create your own DSLs with ease if needed.

---

as a downside, deployment is more complex when you want to leverage the distributed nature of some native features, but you don't need to in general, you can also deploy it like any other ruby/django app iE with a dockerfile and loadbalance it traditionally. Also there is a learning curve in general, since all this stuff _looks_ alien for many devs not used to it, and there are features that don't exist at all in more mainstream languages.

---

[1] except for raw compute tasks, when even Nx doesn't cut it, but then there is rustler for native extensions which works reasonable well!

[2] except for liveview itself - the docs are there but cluttered over many places, and not really within phoenix itself but as an external lib, and there has been lots of changes over time.


BEAM is overall inferior to Kubernetes in terms of features, also BEAM only work with Erlang, so what do other languages do?

I think it's bad design to have your runtime handling those kind of problems, a generic scheduler should be, not the runtime of your language.


Apples to oranges, and complexities in the wrong layer.


The beam is a pretty good scheduler though


I'm more interested in a language like gleam, but the BEAM VM does sound appealing. But one thing I have been wondering is what is the hosting story like for BEAM languages?

Is there easy tooling for deploying to something like AWS ECS and having nodes communicate with each other?


You can host Elixir apps on PaaS like Gigalixir[0] or Fly.io[1] (no associated with these).

I personally use mix release[2] that assembles a tarball of itself (together with BEAM), then rsync that to Hetzner, restart the remote process and viola. I like simplicity.

Re cluster of nodes, the easiest would be to use a library[3] to automate the formation of said cluster.

[0] https://www.gigalixir.com/

[1] https://fly.io/docs/elixir/getting-started/

[2] https://elixir-lang.org/getting-started/mix-otp/config-and-r...

[3] https://github.com/bitwalker/libcluster


A caveat with libcluster + k8s though - it doesn't play nicely with sudden burst of traffic.


To be fair, there are problems with other languages/runtimes and bursty traffic as well - autoscaling isn't great when it takes 20 minutes to provision a new server to run your .Net app.


Could you expand on that or link to something that does? I was considering using libcluster on k8s, so curious about the limitations you're referring to.



Can you talk about this more? :) Why is that the case?


I'll give you a bit of background to explain it better.

Our service is primarily a graphql API. The mobile apps talk to our service, and then it internally talks to other services. We use Absinthe for graphql, and a lot of it is subscription based.

Since these nodes (pods in k8s terms) are clustered, each pod is aware of the other pod. Sometimes we get a huge spike in traffic and the clusters can't start fast enough (we're increasing the scale up time in k8s) and a pod can get OOM killed due to number of graphql subscription and then just go in crashloop. This leads to libcluster thinking the node is still good but when infact it's in crashloop, and thus not allowing any new pods coming up to start up.

We're experimenting with few things, but yeah clustering is not without it's pain


thanks for such a concise answer!


how do you do deploy / bundle your configs?


I compile the tarball using Dockerfile, as the target OS must be the same as source OS to compile it (I deploy Debians on remote, and use Fedora locally). Then there's bunch of mix tasks to bundle the js/css assets - it's all really there ready to be used. The other day I spent half a day implementing same behaviour for Django app.


> Is there easy tooling for deploying to something like AWS ECS and having nodes communicate with each other?

libcluster[0] has a bunch of strategies to form clusters. It seems that ECS supports service discovery through DNS, so the DNSPoll[1] strategy should work.

[0] https://github.com/bitwalker/libcluster [1] https://hexdocs.pm/libcluster/Cluster.Strategy.DNSPoll.html


The answer for any language is just to stick it in a container. Elixir fits inside a container, and the Phoenix generator creates a Dockerfile for you out of the box.


As an aside, Elixir is doing some interesting, novel stuff exploring its own type system. José Valim's keynote at ElixirConf last week went into detail on the topic, so I'd keep an eye out for it on YouTube in the coming weeks if that sort of thing interests you.


I couldn’t imagine working on a large scale project without strong types.

What happens when you have to refactor a large elixir feature on a code base which many teams touch? In such cases you can’t test manually all code paths for runtime errors, so are you just relying (hoping for) perfect test coverage to catch any type related errors you may have caused?


Unless you've worked with Clojure or another immutable, dynamically-typed language with pattern matching, you probably don't have a good mental model for what this would look like. It's a completely different story from a language like Python or JavaScript.

Immutability and pattern-matching get you at least the 80-20 of what a rigid type system does for larger code bases, and your team won't have to be as large when you're using a language like Elixir or Clojure as it would with older, more entrenched languages.


I feel like a common refactor in a large project might be a complete redefinition of a model layer exposed via a bunch of structs.

How does immutability or patter matching save me from runtime errors caused by changing the fields or types inside a struct? Wouldn’t the pattern matching just fail and go down the wrong code path since it was matching for the old pattern?

I feel like immutability is great, pattern matching is great, but static typing is also great and there is no reason why it can’t happily live along side the other two.


In this case, the question is moot.

Elixir structs have compile-time checks: https://elixir-lang.org/getting-started/structs.html


It's not that hard, also Elixir is basically gradually typed with dialyzer. It's not like working on a dynamic and weakly typed lang like vanilla JavaScript or Perl at all.

I do want to clear something up. Elixir is strongly typed, but its not statically typed.

More here: https://www.educative.io/answers/statically-v-dynamically-v-...

Even for langs that are statically/ and strongly typed on the BEAM (like Gleam, whose type system is similar to that of Standard ML or OCaml) still subscribe to the "Let is Crash" philosophy, especially when it comes to messages sent and received between processes. The only thing that is guaranteed is your system will fail at some point, how should the system protect its self form that?

https://www.educative.io/courses/concurrent-data-processing-...

In short, its not like working with Ruby or JavaScript or Python, etc..


The “let it crash” philosophy is great, but at the same time a proper static type system protects you from a whole class of crashes before they ever reach deployment.

If you change the shape of a model object and break its type, it’s great that BEAM will gracefully handle that mistake, but no matter how many times that service restarts, it will still be broken at runtime.

I think type systems have gotten so good in modern languages (Kotlin for example) that it’s a disservice to your org to not use a statically typed language.

I haven’t looked at Dialyzer lately, but is it as robust and easy to use as a first class type system? Having experienced partial typing with annotations with python I must say it’s not nearly as smooth as a proper statically typed language.

I do wish something like Gleam was the front runner language on BEAM - I bet it would get taken a lot more readily.


Dialyzer is good enough for my use-cases, especially in large web apps. In fact, Elixir's dynamic nature, when combined with Dialyzer and the BEAM's fault-tolerance features, offers a reasonable middle ground that has proven robust in large-scale systems.

Comparing it to Python's gradual typing isn't entirely fair for a couple of reasons:

1) Elixir is functional, meaning a value's type never changes. This makes it easier to reason about the code and allows tools like Dialyzer to be more effective.

2) The combination of value/pattern matching and the "let it crash" philosophy is unique to the BEAM ecosystem and has proven invaluable for building complex applications. this out side of Dialyzer gets you 80% the way there. (I don't even use Dialyzer in my applications because I don't think it buys you that much. I lean on testing, typically to cover that last 20%)

I'm intrigued, however by the new type system that's being explored for Elixir by Jose and this team. It promises the best of both worlds: dynamic typing with the assurances of a static one.

If we were to impose a Java/Kotlin-like type system onto Erlang/Elixir, there would be several concerns:

    It could encourage harmful coding practices that hinder code evolution.
    It might conflict with the "let it crash" philosophy, leading to more "nanny coding."
    The effort required to satisfy the type system could outweigh its benefits.
    It could reduce productivity and readability.
    If not integrated into the BEAM core, it might not offer optimization benefits and could create compatibility issues.
    It could divide the community and distract from other important work.
Elixir's existing features like testing, value matching, and the "let it crash" philosophy already provide a robust safety net that a static type system might not significantly improve upon.


A common pattern that I use is to pass a behaviour module as a function argument to support dynamic behavior or dependency injection. Last I looked, I couldn't use dialyzer to describe the behaviour that a function accepts.


Maybe something like fly.io?

I know they support Elixir/Phoenix.

https://fly.io/docs/elixir/the-basics/clustering/


In my experience, deploying BEAM has been just as easy as anything else I can containerize.

WRT getting them to communicate? I ended up giving up on that altogether…

I’m usually good at figuring that stuff out but this one ended up not being worth it (in my case).


What ended up being the problem, maybe is could make this a little clearer (I used https://www.erlang.org/doc/apps/ssl/ssl_distribution as a guide).

Was your requirement to have ssl as the distribution communication mechanism ?


I appreciate it, but it's been a couple of years now, so I can't remember specifically.


We deploy Erlang VMs to EC2 and they communicate just fine. Deploying via a Dockerfile and `mix release` has been a breeze.

As a bonus point, no real need for container orchestration as the BEAM just figures it out.


You already got good answers, I'm only going to add that you can also integrate the self-contained `mix release` final build production artifact with systemd just fine. I've done it.


Phoenix is awesome. Modals are a UX anti-pattern that should be avoided. https://youdontneedamodalwindow.dev/


You may be aware of this already, but the current LiveView generators address many of these concerns by serving the same LiveView template for multiple routes, but the assigns will be different based on which route is accessed. So, for the :index route, the modal will not be visible, but it will be visible for the :new route. Plus, with live patching, you preserve back button functionality (and it even preserves the page state as a bonus). So that addresses the back button problem.

But the problem still exists where clicking outside the modal (or pressing the back button) will destroy the form and any unmodified content, which is super annoying. This can be addressed by listening for changes to the form's input fields and showing a warning when any navigation event occurs when the form is changed-but-not-submitted (easier said than done, but ).

I'm not even disagreeing with your point, really. It's just worth mentioning that 1) many of the problems described have an out-of-the-box solution when using the current LiveView generators, and 2) refinements can be made to address some of the remaining issues.


I would say it depends on the kind of app you are building.


Yes, "it depends". If you're building something internal and Desktop-only then maybe a Modal can be OK. But for a mobile-first app, you will never be able to test it on all the devices people use so consistent UI/UX is impossible. If you have ever done any "in the wild" usability testing with older people with older devices (think iPhone 8 form factor) Modals often break the UX. Seen it happen many times, it's super frustrating to the person trying to use it. :-(


Your link says at the bottom that modals can be used for forms.


I don't think modals are very usable for forms, especially if the form is big – it risks somebody spending a lot of time filling out the form and then closing the modal by accident. I would much prefer a `/resource/[new|edit]`


Phoenix components for the win!

But as a side note, I got rid of modals in my app, as showing modal on mobile devices is bad UX (IMO). Then, my Elixir code became smaller/simpler too. Win-win.


Thank you for your sanity on modals. They are horrible on mobile devices and not necessary in most cases.


Elixir and Phoenix are interesting technologies. I have a good friend that changed from Rails to Phoenix and is very happy with it. I stayed in the Rails ecosystem and am quite happy too and added Go to my toolbelt when I need something with more concurrency. How is the Elixir ecosystem nowadays? Anyone that is active in both ecosystems (Elixir, Ruby) can compare?


I switched from Rails to Phoenix a few years ago and have never looked back. It solves basically all of the frustrations I had with Rails (see e.g. Peter Solnica's writing [0]) and is truly a joy to work with.

If anyone else is thinking of switching from Rails to Phoenix then I humbly recommend my course Phoenix on Rails (http://phoenixonrails.com/). Sorry for the self-promo, but if you use the code HIT8RUN (valid for the next 48 hours) then you can have a 10% discount.

[0] https://solnic.codes/2016/05/22/my-time-with-rails-is-up/


We've been using Elixir + Phoenix in production for about 5 years and I really like the ecosystem.

Phoenix has undergone some bigger changes with recent versions due to the Liveview development, which were a bit annoying to keep up with but in general, everything is very stable and well documented.

Elixir in general is one of my most beloved ecosystems in terms of develper productivity. - Opinionated, configurable formatter, type annotations and checking, very good test and doc tools, awesome community...

It's everything I know from the Ruby + Rails community years ago but dialled up a bit. I haven't done much Ruby work in the last 5 years so I can't provide a direct comparison but I always felt like you really feel the extra 10% of polish Elixir has over Ruby due to the core teams strong involvement in tooling and developer experience.

The only even more streamlined experience for in recent times was Flutter (as long as you don't stray too deep into ffi/native code)


I think the instructions for upgrading Phoenix are pretty much second to none, I just upgraded everything to support the new components system and it is much better than templates because you can have component level state and encapsulation of pieces of your frontend architecture in a React style. It was a pain though you are right! You can also reuse things between normal and live view pages if you break down your components carefully.

I always just look at the number of bugs phoenix has compared to comparable frameworks and it makes me very glad to be using something this stable.


I'm not super active in the ecosystem but Elixir+Phoenix is a true joy, the community is great. The community is also great. Depending on your use case LiveView may or may not be a game changer as well.

It's my goto for any hobby projects these days (used to be Django).


One random concrete example I found while playing with Hotwire is that if you need a full PWA, it's much easier than in LiveView. With Hotwire it JustWorks(tm) while with LiveView it's a giant pain as you have to double up events with controller actions (which is terrible). If you don't need this, though, which many don't, LiveView is cognitively easier simpler its DOM-diffing as opposed to Hotwire's frame-targeting mechanism. To be crystal clear, I'm not saying that targeting frames is hard, just that's it's even easier not have to have to do it at all.


Big fan of both Rails and Phoenix. I use both situationally.


I still don't understand how "dialog [box]" became "modal", just because "modal dialog box" was a thing. It's annoying that "non-modal modal" is a grammatically valid sentence now...


I wish he built a "Edit a form in a slideover". Modals are already part of the core_components and the Phoenix team has done a good job of covering edge cases around CSS transitions. But slideovers have one aspect that's not well covered in modal flow: in/out transitions. Slideovers have a slide-in effect when they are invoked and at the end of transition load the form component which is a live_component. When you cancel/close they slide-out along with the form component. At the end of the transition is when you want to remove the live_component from live_view. Handling these transitions with live_components is very tricky.


Yeah, I agree. Building a really nice slide over is surprisingly hard.


BTW, the Appsignal integration with Phoenix is now really out-of-the-box. I used to have to add custom code to measure Liveview stuff. Now everything works out of the box, it's great.


Completely off topic but sometimes on HN I don't understand how stuff lands on the front page. At the time of this writing, this post has 3 points and 0 comments, yet it is placed nr #3 on the "front page" list.

I get the feeling that certain topics about certain technologies often get at the front page even if there is other threads that have more points and activity that isn't shown on the front page.

Why is that?


From the FAQ:

> How are stories ranked?

> The basic algorithm divides points by a power of the time since a story was submitted. Comments in threads are ranked the same way.

> Other factors affecting rank include user flags, anti-abuse software, software which demotes overheated discussions, account or site weighting, and moderator action.

So if a story gets points very quickly, it will appear on the front page. If it don't keep getting points it will disappear.


It’s probably the same force that drove Phoenix to be at the top of this year’s Stack Overflow Developer Survey of “Most Admired Web Frameworks”: https://survey.stackoverflow.co/2023/#section-admired-and-de...


At the time of me writing this comment it had 9 points after 8 minutes. I guess the ratio of points/time_since_posted is more important than the absolute points.


Sure but as I was writing, it seems like many other stories has more activity in a shorter amount of time but maybe I'm wrong.


Fly.io is involved with YCombinator at https://www.ycombinator.com/companies/fly-io. One of the core contributors of Phoenix also works there and Fly.io tends to tie in with Elixir as a language.

I'm just speculating here but I think a number of posts are curated to land on the home page when you're directly or indirectly related to YCombinator funded companies.


I'm pretty sure time and time again dang has confirmed they don't promote any post coming from a YC-affiliated company, and in case of Elixir, its just one dev at one YC company. A tenuous connection.

I explained what is probably going on in a sibling comment. Less of a conspiracy, and more about a handful of people seeing the hyped language du jour in the title and upvoting it in a matter of minutes.


> I'm pretty sure time and time again dang has confirmed they don't promote any post coming from a YC-affiliated company

Probably the right thing to do ethically if you want to run a forum but at the same time it would be bad business.

I'm not saying that this occurred here and I don't really care either but I wouldn't exactly trust a company on their word on something they can benefit financially from.


"just one dev"

Chris McCord is the creator of Phoenix and this is a post about Phoenix functionality. What you say is likely correct but that's a strong tie.


Elixir-related stories hit the front page of HN several times per week. It seems to be a topic that the HN audience likes to upvote.


Don't quote me on that but it's pretty crude: if it receives N upvotes in a short amount of time, it's promoted to the frontpage quite quickly. If it takes two hours to get the same number of upvotes, it probably gets lost in the neverending ocean of /new.

So it's basically a game of pure chance, a topic that's not too niche, a topic that one upvotes without even reading, and/or good clickbait technique.

HN's algo optimises for popularity, rather than meaty content.


Moderators sometimes put something on the homepage. HN is a little bit curated, it's not just upvotes.


I worked with Elixir daily for about 8 months and it honestly feels to me like the almost the perfect stack for web development. But the one thing that I would like to have is the ability to develop a mobile app that I can put in the app store, but which just runs Elixir LiveView.


LiveView Native is exactly that and being worked on by DockYard. https://native.live


I don't see any links on that page that take me to any code or documentation...


Yeah the page isn't ideal. Project is still early but you can follow it here: https://github.com/liveview-native

#liveview-native on the Elixir slack is a great resource as well to learn more.


I see Elixir on here quite often, what is the appeal and why are many companies switching to Elixir?

Last I checked a while ago Brex famously used to be on Elixir but now are on Kotlin.

https://medium.com/brexeng/building-backend-services-with-ko...


Elixir+Phoenix does web stuff very well, with little maintenance required (i've upgraded 4+ years old project in two ot three days, time mostly spent on upgrading some 3rd party libs that bumped major version). Unlike ruby, it's really easy to understand what's going on (no hidden state, all variables are passed explicitly, imports are stored in one file (in phoenix) you can look at or explicit as well.

With added LiveView on top, you could avoid writing a lot of SPA react (vue, svelte etc) code (some limitations apply, but you can do a lot), spending less people, time and resources for the same result.

Traditional setup: backend logic + backend api + react SPA + logic for calling backend api

LiveVew setup: phoenix backend + LiveView views + a bit of glue code (in elixir) to replace onclick etc stuff


For those reading who are not able to switch stacks, these same ideas are being applied in other languages very successfully as well.

1. Laravel Livewire for PHP

2. Hotwire for Rails/Ruby

3. Blazor for C#/.NET

4. HTMX* as a general tool for any other web server

5. React Server Components (if you squint hard enough)

Phoenix Liveview definitely started the trend by showing a mature implementation of these ideas on the same level as the application developer.

I would argue number 5 is a bit of a meme, since you still have to write a ton of JS, but if you're more interested in the architecture ideas for structuring your app, there is an interesting parallel that I think can be drawn.

[*] HTMX doesn't really embrace the idea of calling a function from your server by name, but the ergonomics are similar when writing frontend code.


Laravel Livewire is… frustrating. I used it for 1-2 years and ended up learning Elixir so I could use LiveView instead.

Livewires performance is terrible for anything other than very basic components. The fact that it has to rebuild state on every interaction makes it a pretty poor tool for most use cases.


Not sure if you've seen that v3 was released. Caleb spent a lot of effort to solve many of the performance problems. It's still not as lean as Liveview (and nothing probably will be) but it's much much better than it was.


I saw it was released but never looked into it as there's no reason to now that I've moved to LiveView.

I have other issues with Livewire as well, including how Caleb operates his communities. He has and continues to make a ton of money off Livewire and still provides zero support to the community. Want any actual support? Well that starts at $6,000/year for one support request a month.

He doesn't even appear to be a member of his own discord server anymore. Not that it makes a difference; last time I checked had only ever sent 34 messages in there and the last one was in 20202. He has one guy who would randomly show up around once a day and answer some of the questions.

I don't expect free support but if your package is so confusing that the community is unable to support each other, you should probably be around trying to help sort that out. Instead, he just keeps doing re-writes which puts the the load on everyone else.

Anyways; if you're interested in this type of project I HIGHLY recommend you check out Elixir/Phoenix/LiveView. I haven't enjoyed writing software this much for a long time; not only is the language and framework more enjoyable to work with, but the community is so much better in general.


I can't speak for other companies or devs, but as a relatively junior developer I quite enjoy working in Elixir, and especially with Phoenix and the Ecto ORM.

The syntax reads and writes very well. When I now have to write other languages, mainly Typescript, I miss native pattern matching and the pipe operator.


Plenty of languages can get a solid standard library to write most code with, but only elixir gives you a modern, simple standard library with the tools to scale an app as high as apps can be scaled.

Whatsapp famously got to 1 billion messages a day with only 11 engineers on the BEAM (the VM that elixir runs on). It has proven itself immensely capable at the highest levels of scale so the only thing for anyone to decide is whether the stdlib and tooling is to their liking (speaking mostly in the context of networked IO bound applications, which is most things on the internet)


I love Elixir, but I don't agree that it's the only language with a great standard library. Go has one too.


I probably worded my statement poorly, but my intention wasn't to claim it was the only language with a great stdlib. I would disagree that go has a good stdlib, I think it's quite poor, but I do believe plenty of other languages have great stdlibs.


We (Mirego) made the move from Rails to Elixir years ago for three main reasons: productivity, maintainability and performance → https://shift.mirego.com/en/elixir-functional-programming


Really interesting read! I was always curious about Elixir but we've been using kotlin in the backend for years now an I'm really happy (except the JVM and spring bullshit stuff). The language tho is on another level. Lot's of compile-time safety and syntatic sugar. We're really productive with that.


My understanding from talking to some former Brex developers was that the switch was entirely because Kotlin is the CTO's favorite language and everything else was just a post-facto justification. So take it with a grain of salt.


"many" not really.


Elixir is bolted on top of erlang so reading error stacks with erlang is common, needing to grok erlang concepts and docs is also sometimes needed. This makes it odd to work with. I know if I'm using a Java, Ruby, Python or PHP framework (django, laravel, rails, whatever latest java web framework) I can read thru docs or source code and troubleshoot stack traces without having to learn another language. Its unavoidable with Elixir beyond simple apps.


I barely know Erlang and life has been fine. I do know the runtime characteristics of the Beam VM and occasionally I need to read Erlang docs, but compared to other stacks the experience has been significantly more pleasing.

People are of course different and I fully acknowledge that things that seem normal to me may seem odd to others, so YMMV.


Erlang is a very simple language though especially compared to elixir. The runtime semantics are fairly unusual but it almost completely shares those with elixir so you'll have to learn them anyway. The BEAM is very complex but again you have to learn that anyway.


I hear you and it has been an issue years ago but gradually Erlang's maintainers have been making error messages (and return error values) better and more readable and at this point I can't remember when was the last time when an Erlang return value and stack trace have impeded me.

So you were correct some years ago but I am not seeing this nowadays. So yeah, valid criticism, at the same time this criticism has been mostly taken to heart and addressed as of today.


The syntax is a little different but the semantics are exactly the same, so it's trivial I guess?

also, the errors you get, when they are in erlang are in valid erlang, i can't say that about Java, Ruby, Python or PHP which give you errors in English.

https://hackernoon.com/why-is-erlang-the-only-true-computer-...


For some things like SSL/TLS, Elixir is mostly just syntactic sugar over erlang features. I didn't find it trivial when I was trying to figure out SSL/TLS issue but worked fine on same OS but different language stack. Keeping track of versions+patches of Erlang, Elixir and Phoenix for a web app may be trivial until you run into something where its not Elixir then you have to dive into erlang things. I was merely pointing out it is in fact another step people may have to take. Something to consider when evaluating languages. I ran into this with an app that does a lot of API calls externally, dealing with many varying TLS certificates.

Fans of Elixir out in force today downvoting dissenting opinions even though its valid.


All opinions are valid. this point isn't particularly special though.

In almost every lang you'll run into something that your aren't familiar with and you'll have to dive into something you aren't comfortable with. I had to dive into some C code when ruby decided to segfault. I've had to dive into Java JVM internals when working in Clojure.

So I'm not sure this is a "elixir" thing as much as a "I'm a developer thats supposed to know multiple languages and stacks" kinda thing.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: