Yeah, all thought would love to see a high performance one, with minimum allocations. I believe that the BEAM could properly serve the fastest, extreme concurrency one across languages, most of the tools are almost in place to do this, with regards to json and etc.
Yeah, I’m aware of it, but I meant the actual framework code being less boilerplate-y.
IMHO, the playground is good for quick testing/ prototyping and creating repros, but I wouldn’t expect someone to actually deploy it to production… In other words, I wouldn’t mind if Phoenix had more conventions or hid the defaults a bit more
.
To be fair, I didn’t even remember that XD
BTW, @chrismccord, have you ever considered partnering with folks behind some of these other projects? I tend to see them less as separate initiatives and more as opportunities to build stronger foundations together (Surface comes to mind). I remember chatting with @bartblast about Hologram at some point, and I’m always curious whether the authors in this space had a chance to connect.
Chris, thank you so much for the kind words and for sharing phoenix_playground! Coming from you, this means a lot. ![]()
I’m actually at a crossroads right now about Nex’s architecture, and your input would be invaluable:
The dilemma:
Should Nex use LiveView or stick with HTMX for its file-based routing approach?
I’ve created a GitHub Discussion to explore this: 🏗️ Building Nex: The Dilemma of HTMX vs. LiveView - We Need Your Input! · gofenix/nex · Discussion #1 · GitHub
My current thinking:
LiveView approach:
- More powerful and “Phoenix-native”
- Better real-time capabilities
- But might lose the simplicity that makes Nex appealing to beginners
HTMX approach:
- Simpler mental model (closer to traditional web dev)
- Lower barrier to entry
- But might be reinventing what LiveView already does well
phoenix_playground shows how elegant LiveView can be with minimal boilerplate. Maybe the answer is to embrace LiveView but provide the file-based routing and conventions that make Nex feel simple?
Would love your thoughts on this - especially since you’ve thought deeply about developer experience with Phoenix.
Do you need to decide that for your users? I‘ve always imagined file based routing as just another router implementation alongside Plug.Router or Phoenix.Router. I can see how you need to kinda know what a user might want to use, but when you can support a usecase why not do so.
I hear you, but I lean toward frameworks being opinionated rather than trying to support every possible approach.
Let me clarify what I’m actually wrestling with though - not the routing layer, but the interaction model within pages:
HTMX approach:
- Template:
hx-get="/xxx" - Code:
def xxx do - Pros: Intuitive, direct mapping to routes
- Cons: Many hx-* attributes to write
LiveView approach:
- Template:
phx-click="xxx" - Code:
def handle_event("xxx", ...) do - Pros: Cleaner templates
- Cons: More boilerplate (every event is handle_event)
But I’d love your take - which DX feels better to you?
I like your current direction but I think it can be even simpler by using datastar. I feel like if people want Liveview they’ll just use that. The benefits of a framework like this would be:
- Minimalism
- No websocket needed
- Stateless or stateful, mix and match
I think with a few tweaks it could have a more declarative feel. You could even run everything through Nex.Store so you have that same “change state, the UI updates”. Imagine something like this:
defmodule MyApp.Pages.Todos do
use Nex.Page
def mount(_params) do
%{todos: Todos.all()} # this could automatically init the Store or it could be made more explicit
end
def render(assigns) do
~H"""
<h1>My Todos</h1>
<form data-on:submit="@post('/add_todo')" >
<input type="text" name="title" required />
<button>Add</button>
</form>
<ul id="todos">
<li :for={todo <- @todos}>{todo.title}</li>
</ul>
"""
end
def add_todo(%{"title" => title}) do
todo = Todos.create(title)
Store.update(:todos, &[todo | &1])
end
end
When the store is updated, it would handle sending the html via datastar’s patch_elements. The framework could use fat morph by default or maybe automatically use the append option if it’s a list. The convention would be that the store key should match the element id.
If someone didn’t want to use the store, they could still use Nex.patch_elements("#todos", …) directly though maybe that too could be simplified / renamed if you didn’t want to expose the implementation details.
A few of other ideas:
- Take it to the next level by making true optimistic UI easy (something Liveview lacks)
- Might be nice to be able to break free from file-based routing by using a
routemacro along the lines ofHologram. - Might be cool to be able to use
templefor an all-elixir feel (maybe this is already possible).
I really like this direction! I was actually considering htmx + Alpine.js before.
I saw on the htmx website:
Datastar started life as a proposed rewrite of htmx in typescript and with modern tooling. It eventually became its own project and takes an SSE-oriented approach to hypermedia.
Datastar combines functionality found in both htmx and Alpine.js into a single, tidy package that is smaller than htmx.
This is a really promising approach. I need to explore and research Datastar more deeply. Thanks for the detailed suggestion!
Hi! I had replied to your discussion on GH, but since there are some ongoing discussions on Reddit as well, I thought that posting here would give it more visibility.
I’ve shared this with the author of Hologram, so I might as well make my opinion public here: I think it’s common knowledge at this point that Chris McCord’s always wanted to build something like LiveView, and Phoenix was basically a means to get there.
What I would really love to see is LiveView becoming a generic engine to power client and server live interactions, so other frameworks (like Nex) have a chance to innovate on making things simpler (FYI, I still have hopes that HEEx will get decoupled from LiveView at some point).
I tend to agree with @LostKobrakai here about delegating the rendering pattern to users. However, you might also end up locking yourself in by building Nex on top of LiveView - unless you find a way to cooperate with folks over there towards a common goal.
That being said, I’ve seen some interesting replies to your reddit post where people mentioned that SSE has better ergonomics than WS - which I don’t know if it’s true or not, but it surely makes the whole experience feel more “native” to me.
Phoenix and LiveView do have this weird gap today, which causes some “impedance mismatch” because conn and socket don’t have a lot in common, which creates some annoyances like the separate pipelines or layouts being handled differently than standard components (although I think this got fixed).
Anyways, to answer your question, what I think LiveView does very well is that it allows you to build real-time apps with great interaction quite effortlessly, but I also hate all the boilerplate XD. Also, HEEx templating is great, and the component model is fine; so if you can get to a similar experience with a HOTW (HTML Over The Wire) approach, that would be even better.
In other words, while I would love for the community to cooperate on having better foundations and branching out where we diverge, I know this is not always possible, so thanks for starting the conversation - we definitely need to explore more ideas!
![]()
PS.: I didn’t know about Datastar, it seems really, really cool!
fyi, looks like someone created an Elixir Datastar SDK you could build on top of or use for inspiration datastar_sse | Hex
Hey @zhenfeng-zhu! Congrats on the Nex launch – it’s great to see more innovation in the Elixir web ecosystem.
Quick thought on the HTMX vs Datastar vs LiveView wrapper approach (saw the Reddit thread as well): I’d suggest focusing on either HTMX or Datastar rather than creating a LiveView wrapper, since LiveView itself could evolve to adopt similar simplification patterns over time – or evolve in other directions entirely. The key issue is that you wouldn’t control that evolution.
@thiagomajesk – I appreciate your thoughts from our earlier conversation about coordination in the community. While I understand the desire for consolidation, I think there’s real value in having different opinionated solutions that take distinct approaches. It’s not always about competing for the same users – often it’s about growing the Elixir pie by offering developers choices that match their specific needs and philosophies.
The simplicity-first philosophy that Nex is pursuing definitely resonates, and I’m heading in a similar direction with Hologram’s standalone mode (which is admittedly long overdue – sorry about that! – but the funding side quest took quite a lot of time, though successful. Big news coming soon). The key difference is the approach: server-driven frameworks like LiveView, HTMX, and Datastar excel at certain use cases, while Hologram takes a different path by compiling Elixir to JavaScript and running it client-side. This avoids latency issues and opens the door to local-first features down the road.
Different problems, different solutions – and that diversity can strengthen the ecosystem as a whole.
Either is fine. DX means nothing if the #1 user is yourself. Can I ask you a blunt question, what does it do that the leading framework (Liveview) doesn’t?
I ask this question because I am also slowly building my own realtime web framework. My beef with LV is that it does not work very well on lossy or high latency networks. What is the itch that you want to scratch?
To add t the discussion a bit more: I also considered to use SSE as a mean to do real time web. After written some code and did some experiments, I realized that SSE is just a poor man’s websocket; it is not going to perform well in the situations where websocket start failing. Basically, streaming from server to the client is fundamentally broken in a congested network; the only way out is to do client side polling.
Exciting! Let me know if I can make anything easier from Bandit/Websock/Plug’s perspective!
Really looking forward to this. Hologram is a game changer for the Elixir community. Hoping that the community’s leading voices see that and champion / financially support it.






















