[HN Gopher] LiveView Is Best with Svelte
       ___________________________________________________________________
        
       LiveView Is Best with Svelte
        
       Author : keturakis
       Score  : 243 points
       Date   : 2024-04-03 11:41 UTC (11 hours ago)
        
 (HTM) web link (blog.sequin.io)
 (TXT) w3m dump (blog.sequin.io)
        
       | rc_mob wrote:
       | I'm a noob but it looks like this overlaps with nextjs a lot?
        
         | PKop wrote:
         | LiveView and Elixir/Erlang have stateful processes on the
         | server unlike pure stateless HTTP request/response. This
         | fundamental difference is what makes LiveView unique. Next.js
         | isn't passing messages over a websocket nor holding stateful
         | processes on the server.
        
       | POiNTx wrote:
       | I created LiveSvelte, let me know if you have any questions :)
        
         | wturner wrote:
         | Is there any reason you can think of to still use JS Hooks if
         | using LiveSvelte?
        
           | POiNTx wrote:
           | With hooks you are able to render your html server side while
           | still having some js functionality. Technically you can also
           | render server side with LiveSvelte as it supports SSR out of
           | the box, but this SSR uses Node and that introduces a slight
           | performance decrease (around 3ms I believe).
           | 
           | I've been looking at Bun to see if it would help but it's
           | still unclear to me.
           | 
           | Heex rendering is just way faster.
           | 
           | If you don't care about SSR for certain components (for
           | example modals, they don't need SSR generally), then I don't
           | see a clear advantage for hooks.
        
           | victorbjorklund wrote:
           | If you just need one simple thing in your app that uses JS it
           | might be overkill to bring in LiveSvelte only for that.
        
             | POiNTx wrote:
             | That's true. And another downside is that once you're in
             | the Svelte environment you can't use your Phoenix
             | components inside those Svelte components.
             | 
             | I've thought about adding a library of default Svelte
             | components which mirror the core components you get from
             | Phoenix out of the box. But then again you lose forms and
             | changesets etc, it's just annoying.
             | 
             | Where I see LiveSvelte fit is where you really need a lot
             | of complex client side state. Sprinkle it in, but keep
             | using phoenix components as your default, even with hooks
        
       | kevinak wrote:
       | Great project! Superb timing here. Just released our Svelte Radio
       | episode about this: https://www.svelteradio.com/episodes/phoenix-
       | liveview-and-sv...
        
         | xrd wrote:
         | I'm so excited about this, I've never been able to rectify
         | LiveView and Svelte. I love hearing about the philosophies of
         | Svelte builders so this will be an extra special episode.
        
       | bogwog wrote:
       | So instead of managing state on the client, you manage state on
       | the client _and_ the server? That doesn 't seem like an
       | improvement, even if it saves you from having to build yet
       | another API.
        
         | kevinak wrote:
         | Some things just end up being a better experience fully client-
         | side. Don't go all in on it - just do it when it makes sense.
         | 
         | Another thing I like about this is the ability to be able to
         | use Svelte as a templating language rather than Heex.
        
         | pjmlp wrote:
         | It is just a new generation rediscovering ColdFusion, Web
         | Forms, JSF, PHP, Spring, Rails...
        
           | dns_snek wrote:
           | Could you elaborate? I don't see many similarities between
           | those and LiveView.
           | 
           | The difference between traditional technologies that render
           | HTML server-side and LiveView, is a persistent connection to
           | the server which allows it to re-render templates in response
           | to server-side events and patch client-side HTML without
           | writing any Javascript.
        
             | pjmlp wrote:
             | Mostly based on WebSockets and Server Push.
             | 
             | As one example of such approaches, .NET has SignalR since
             | 2013.
             | 
             | And WebForms could use designer tooling since 2001, and
             | then there was ASP.NET AJAX Control Toolkit.
        
               | pdimitar wrote:
               | But it doesn't have the BEAM VM. The runtime matters a
               | lot, and LiveView wouldn't work as well if it wasn't
               | running under the BEAM.
        
               | pjmlp wrote:
               | Tomato, Tomato, it has another VM.
        
               | pdimitar wrote:
               | It's your right to delude yourself that the runtime does
               | not matter. That's not a discussion I am willing to have
               | though, especially when exactly 100% of my 22+ years of
               | programming experience have demonstrated, time and again,
               | that the runtime inevitably ends up making a lot of
               | difference (sometimes all the difference even).
               | 
               | Or, when you don't have a runtime -- as is the case with
               | Rust, kinda sorta I mean because technically `tokio` can
               | be classified as a runtime -- then you rely on a stricter
               | compiler.
               | 
               | Both strategies work pretty well.
               | 
               | I am not shitting on C# / .NET, they are solid as hell.
               | But some things the BEAM VM just does better and everyone
               | who worked with old-school VMs (in my case the JVM) and
               | the BEAM VM can tell you that.
               | 
               | But again, you do you, think what you will. -\\_(tsu)_/-
        
               | OJFord wrote:
               | This saying really doesn't work in writing, I just read
               | ..err.. 'tomato, tomato'
        
               | jddj wrote:
               | This isn't particularly convincing, as the pattern --
               | loosely: keep a websocket open and keep the formerly
               | clientside app state serverside while passing events and
               | pushing diffs -- seems to appear successfully outside of
               | the BEAM vm. For example, blazor serverside (.net) and
               | laravel livewire (php).
               | 
               | I haven't checked but I'm sure there will be a python one
               | too
        
               | pdimitar wrote:
               | You are not convinced because you don't know the details.
               | But I am not paid to advocate or to even try to convince.
               | You've been informed now -- from here on it's on you as
               | to whether to remain biased or to expand your horizons.
        
               | jddj wrote:
               | I've written elixir apps, also read Armstrong's thesis,
               | etc etc. Beam is undoubtedly an excellent piece of
               | engineering.
               | 
               | I don't want to engage more than that, as the horizons
               | comment seems bizarre in the context of the thread
        
               | pdimitar wrote:
               | No need to get defensive. Your comment came across as
               | curmudgeon-y and biased, I called you out for it, you
               | could have agreed to disagree which I would respect. But
               | no, you had to go out of your way to try and strike.
               | 
               | Well, OK. But HN is not the place for that and I refuse
               | to engage further.
        
               | dns_snek wrote:
               | Not quite, I'd say that SignalR is comparable to Phoenix
               | Channels. It's a communication protocol that can use
               | different transport protocols, Websockets being one of
               | them.
               | 
               | LiveView builds on top of Phoenix Sockets. When the page
               | is loaded for the first time, it starts a lightweight
               | server-side process on the BEAM VM. This long-lived
               | process renders the HTML template (which can consist of
               | multiple SPA-style components) and keeps all of the
               | relevant "props" (called assigns) in-memory.
               | 
               | Every time a new event is received, either client-side
               | (e.g. button click) or server-side (typically via a
               | PubSub subscription), that long-running process will
               | update its assigns (props) to reflect the new state. The
               | framework then intelligently re-renders parts of the HTML
               | template which depend on those modified assigns, and
               | sends a minimal HTML diff to the client.
               | 
               | All of this can be done without writing any custom JS.
               | Basic client-side events are usually set up with special
               | HTML attributes like `phx-click=my_custom_event` and
               | automatically wired up by LiveView JS bundle to be
               | received by that long-running process.
        
           | ramon156 wrote:
           | What does php spring and rails have to do with this? I'm
           | confused haha
        
             | pjmlp wrote:
             | Keeping sessions on both sides.
        
           | ahallock wrote:
           | Sounds pretty reductive and dismissive. Have you actually
           | used LiveView and compared the DX? I've used a a few of the
           | technologies you listed, and LiveView is a different animal.
        
         | klabb3 wrote:
         | Are you comparing with PWAs? Or what's the baseline? Because
         | with PWAs you have both too. State is accessed from the client
         | with requests and you have to manage caching and stale state as
         | well, to ensure performance and not drifting out of sync across
         | components, no? Last I checked out a modern "performant"
         | graphql stack - it was horrifyingly complex and full of knobs.
        
         | MatthiasPortzel wrote:
         | Eventually, some form of this paradigm is going to win.
         | 
         | In practice, applications need state on both the client and the
         | server. The server needs the authoritative state information
         | (since the client is untrusted), but the client needs to be
         | able to re-render in response to user interaction without a
         | round-trip.
        
         | riskable wrote:
         | It's never that simple. In web applications there's always
         | these types of states:                   * States that the
         | client needs to keep track of         * States that the server
         | needs to keep track of
         | 
         | Then on top of those there's two more kinds of states that
         | overlap but they're not quite the same thing:
         | * States that only need to exist in memory (i.e. transient)
         | * States that need to persist between sessions
         | 
         | There's a seemingly infinite number of ways to manage these
         | things and because "there's no correct way to do anything in
         | JavaScript" you either use a framework's chosen way to deal
         | with them or you do it on an ad-hoc basis (aka "chaos" haha).
         | 
         | In the last sophisticated SPA I wrote I had it perform a sync
         | whenever the client loaded the page. Every local state or asset
         | had a datetime-based hash associated with it and if it didn't
         | match what was on the server the server would send down an
         | updated version (of whatever that thing was; whether it be
         | simple variables, a huge JSON object, or whole images/audio
         | blobs).
         | 
         | Whenever the client did something that required a change in
         | state on the server it would send an update of that state over
         | a WebSocket (99% of the app was WebSocket stuff). I didn't use
         | any sort of sophisticated framework or pattern: If I was
         | writing the code and thought, "the server needs to keep track
         | of this" I'd have it send a message to the server with the new
         | state and it would be up to the server whether or not that
         | state should be synchronized on page load.
         | 
         | IMHO, that's about as simple a mechanism as you can get for
         | managing this sort of thing. WebSockets are a godsend for
         | managing state.
        
         | realusername wrote:
         | You already manage two kinds of state when you are building a
         | React app:
         | 
         | - State coming from the server as a result of user actions
         | 
         | - Local state which isn't intended to be shared to the server,
         | usually UI stuff.
        
         | open592 wrote:
         | This is no different than any other optimization performed in
         | any other software ecosystem. There is no reason to do this
         | unless you have to. And the reason you would have to is because
         | of performance and user experience.
         | 
         | When your web application requires the following:
         | 
         | - Large amount of user interaction (requires client side
         | JavaScript)
         | 
         | - Large amount of experimentation (bundle is not static,
         | changes per request)
         | 
         | You are going to want to split up the logic on the server and
         | client to reduce the amount of JavaScript you're sending to the
         | client. Otherwise you have a <N>MB JavaScript bundle of all the
         | permutations you're application could encounter. This may be
         | fine for something like a web version of Photoshop where the
         | user understands that an initial load time is required. But for
         | something like Stripe, Gmail, etc. where the user expects the
         | application to load instantly you want to reduce the initial
         | latency of the page.
         | 
         | You can move everything to the server, but like GitHub
         | experienced you then encounter a problem where user interaction
         | on the page suffers because user actions which are expected to
         | be instant, instead require a round trip to the server (speed
         | of light and server distribution then becomes an issue).
         | 
         | You can lazy load bundles with something like async import, but
         | then you run into the waterfall problem, where the lazy loaded
         | JavaScript then needs to make a request to fetch it's own data,
         | and you're left making two requests for everything.
         | 
         | If you encounter all these problems then you end up reaching
         | for solution which make it easier to manage the complex problem
         | of sharing logic/state between the client and the server.
        
         | matlin wrote:
         | Yeah that is the crux of most modern three-tiered architectures
         | (client<->server<->database) these days. We're working on
         | simplifying this with a new concept: a full-stack database.
         | 
         | If you run an identical query engine on client and server and
         | then sync data between them, a client can just write a normal
         | query on the client and you get an optimistic response
         | instantly from a local cache and then later a response from the
         | authoritative server. Frankly, this is where most highly
         | interactive apps (like Whatsapp, Linear, Figma, etc) end up
         | anyway with bespoke solutions we're just making it general
         | purpose.
        
           | bogwog wrote:
           | That sounds a lot like CouchDB and PouchDB. I haven't used
           | the latter, but CouchDB provides a standard REST API (with
           | authentication) out of the box. You'll probably need to add a
           | custom API for more complex stuff, integrating with other
           | services, etc. But all the boring CRUD stuff is already built
           | into the database.
           | 
           | But more stuff like this is always welcome!
        
         | akira2501 wrote:
         | > build yet another API.
         | 
         | It appears that's one of their major problems. They're not
         | "building" APIs. They're just slapping "one shots" onto the
         | side of a router whenever the need arises. This speaks to a
         | complete lack of a planning and design phase.
         | 
         | I guess if you want to build something without any plan
         | whatsoever, this might be a way to "improve" that process, but
         | there's a much simpler one that doesn't require your team to
         | become polarized over a framework.
        
       | bcardarella wrote:
       | We use Svelte along with LiveView in BeaconCMS. There are
       | certainly good use cases for wanting something that has more
       | granular control of the UI on the client but I would caution
       | teams from just going all-in on Svelte + LV for all things. Even
       | with Phoenix using LiveView isn't always the answer as sometimes
       | dead render pages are perfectly fine. Don't all-or-nothing
       | everything.
       | 
       | As the article points out there are some good use cases for
       | deviating from the 'LiveView Way'. I would argue that if you have
       | 1,000ms round trips then there is something else to consider but
       | geographically located servers could be unavailable to your team
       | for a number of reasons (i.e. cost) so adding some client-side
       | state management could be your solution.
        
       | submain wrote:
       | I am not familiar with LiveView, so I'm curious. Looks like it
       | processes UI actions server side.
       | 
       | So, are all client interactions sent through the websocket? I
       | remember years/decades ago we used to do that with ASP.NET, where
       | every single component interaction was handled by the server. How
       | is this different / better?
        
         | bcardarella wrote:
         | I never used ASP.net so I cannot offer a comparison about what
         | is "better" but your assumption is correct that diffs are
         | through a WS and merged client-side. What this has resulted in
         | is actual order of magnitude of implementation time reduction
         | over the crazier SPA complexity available today. Less time to
         | build, less cost to the company, less bugs in the long run, and
         | a single place to manage and reason about state. It's a win.
        
           | bornfreddy wrote:
           | But isn't there a delay in UI responses because of latency
           | then?
        
             | cess11 wrote:
             | Sure, it's not for a smooth user experience over 2G
             | connection, if that's your audience you'd use ordinary
             | template rendering with Phoenix, or use it for a JSON API
             | and build a JS client that talks to it.
        
         | cess11 wrote:
         | This is run on the BEAM VM, so a LiveView is a lightweight
         | process hooking up the view to the bells and whistles of the
         | BEAM, including relatively easy Pub/Sub, soft-realtime
         | monitoring and so on.
         | 
         | Some people think it's kind of nice to have one programming
         | language for everything, including queues, cache, database
         | queries, client layout, business logic.
        
         | victorbjorklund wrote:
         | You could do that but in general no not in production. If you
         | just have a UI update that server doesnt need to know about
         | (for example opening a menu) then you do it with javascript.
        
         | Muromec wrote:
         | Vanilla live view does exactly that, but I think the point of
         | trowing svelte (or any other frontend) into the mix is to keep
         | _some_ updates frontend-only.
         | 
         | It seems to go against the wisdom of the last few decades, but
         | the network latency seems to permit it now. Throw some edge
         | computing to the mix and maybe it's all a good idea.
        
       | klabb3 wrote:
       | Generally speaking this is the model I've always been wanted to
       | build apps in. Event oriented, bidirectional realtime updates
       | with server, ordered events, local and remote state...
       | 
       | I didn't know about LiveView and never used erlang-family
       | languages, but definitely they're onto something. The traditional
       | request-response model is many times causing a lot of subtle
       | problems with consistency and staleness.
       | 
       | A wishful (probably also controversial) thought: if the last
       | decade was about integrating FP concepts into mainstream
       | languages, then I hope the next decade will be oriented around
       | integrating stateful message-oriented (reactive?) programming
       | into the mainstream full stack.
        
         | nmk wrote:
         | > I hope the next decade will be oriented around integrating
         | stateful message-oriented (reactive?) programming into the
         | mainstream full stack
         | 
         | Also known as MVC before Rails decided to redefine the term.
        
           | DonHopkins wrote:
           | Java redefined the term MVC a long time after Smalltalk
           | originally defined the term in the 70's. Rails didn't
           | redefine the term, it much later copied the (poorly)
           | redefined term from Java and tweaked it a little. Smalltalk
           | MVC and Java/Rails MVC are EXTREMELY different. Java and
           | Ruby's MVC are quite similar (and loosely based on a
           | superficial misunderstanding Smalltalk's MVC).
        
           | klabb3 wrote:
           | Maybe? Most good ideas have been out there for decades.
           | Getting the execution right is what's hard.
        
           | andrewflnr wrote:
           | No, MVC is at best orthogonal to message-passing.
        
         | cess11 wrote:
         | You can use asdf to install erlang/BEAM/OTP and elixir, takes a
         | few minutes if you have some previous experience with the tool.
         | 
         | Either way it'll probably take about two hours to have your
         | first rudimentary Phoenix chat application loaded in a browser
         | if you follow some guides and tinker around a bit.
        
           | square_usual wrote:
           | I would strongly recommend using mise instead of asdf. It's a
           | drop in replacement that is just flat out better for most
           | people.
        
         | floodfx wrote:
         | There are LiveView backends written in Javascript
         | (http://liveviewjs.com), Go
         | (https://github.com/canopyclimate/golive), Java
         | (https://github.com/floodfx/undead), and Python
         | (https://github.com/ogrodnek/pyview).
         | 
         | Disclaimer: I wrote or helped write the first three.
        
       | fearthetelomere wrote:
       | This looks super promising...
       | 
       | I very much relate to the dropdown example, and I've found that
       | complicated UX patterns can be extremely awkward to implement and
       | maintain in LV.
       | 
       | One example from my experience that was prickly to implement in
       | LV was graying out a chat message you sent if it didn't get acked
       | or persisted by the channel/server for any reason.
       | 
       | Can't wait to try this out in my next project!
        
       | nvegater wrote:
       | I honestly don't understand how's this different from react
       | server components with nextjs but with less features? It seems
       | like the same thing but with an even clearer border between
       | server/client components and therefore missing all the
       | optimizations (like streaming). Like islands architecture but
       | made out of different technologies, is my understanding correct ?
       | I would appreciate some feedback :)
        
         | bcardarella wrote:
         | LiveView has streaming. I would argue that if you're stuck in
         | the React way of thinking about application design then it's
         | not worth trying to sell you on what LiveView is doing. But
         | there are multiple case studies out there showing that it
         | results in far less build times than React for no compromise on
         | user experience.
        
         | terandle wrote:
         | Yeah I wish this article had covered how this solution compares
         | to React Server Components as it kind of looks like spaghetti
         | of different techs compared to how next.js streamlines the same
         | problem space into one consistent mental model.
        
       | atonse wrote:
       | I've wanted something like this for Vue/React too with LiveView,
       | because then you get access to this massive ecosystem of great
       | components to put in your phoenix apps while still utilizing
       | LiveView. (the LiveView component ecosystem is tiny).
       | 
       | So maybe this can be the start of a general bridge that can
       | bridge LV with React or Vue components too? And make it easy to
       | put these in a page and interact with LV events, etc.
        
         | yurishimo wrote:
         | There is an adapter already for Inertia.js and Phoenix.
         | https://github.com/devato/inertia_phoenix
        
         | dugmartin wrote:
         | I created a useLiveView() hook a couple of years ago for a
         | couple of personal side projects. It was pretty straightforward
         | and let me have bi-directional state.
         | 
         | The only big downside is you also need to setup server side
         | React rendering for the initial load if you care about SEO.
         | 
         | Maybe I should dig it up and post it in a gist somewhere (I
         | don't want to maintain an open source library for it).
        
         | bezieio wrote:
         | I've recently developed a LV/React bridge and am using it on a
         | production app, but nothing open sourced at the moment. I'll
         | open it up at some point soon and try and post back here!
        
       | baskind wrote:
       | Nice solution!
       | 
       | In my app, I use reusable Stimulus controllers alongside
       | LiveView, and it works seamlessly as well.
       | 
       | On a general note, while it's a pleasure to build with LiveView,
       | the more I use it in real-life scenarios, the more I realize the
       | benefits of stateless HTTP frameworks like Hotwire, which feel
       | more performant and resilient to reconnections, and avoid the
       | need to place more servers close to users for stability.
        
         | MatthiasPortzel wrote:
         | When Stimulus/Turbo was first announced, I was really hoping it
         | would help with the problems that the author describes.
         | 
         | Unfortunately, Stimulus doesn't actually provide an elegant way
         | to keep state on the client. "A stimulus application's state
         | lives as attributes in the DOM." This means that it's not
         | better than vanilla JS or jQuery.
         | 
         | Edit: I haven't used Stimulus for a real project; it's possible
         | their values and change callbacks are a better experience than
         | I originally imagined.
        
         | sph wrote:
         | Yeah I use Stimulus and Live View together as well. It is the
         | right level of complexity, while I feel Svelte deals with a lot
         | of stuff which is not even an issue when paired with LV. All
         | you need is vanilla JS or a thin layer on top of it, not an
         | entire framework. You will not have to write a lot of JS after
         | all.
         | 
         | My production app has no more than 200 lines of JS, and I could
         | probably get rid of a couple Stimulus controllers. Live View is
         | that good. I also made a very hacky Stimulus-Live View hook
         | adapter, so my Stimulus controller can send events directly to
         | the LV process.
         | 
         | EDIT: Live View does not require you to run geo-distributed
         | servers at all, unless you have bought into the fly.io kool aid
         | a little too much. And it deals with disconnections
         | beautifully. I didn't even have to do anything to support zero-
         | downtime updates. The client loses connection to the WebSocket
         | and reconnects to the new version, restores the state, all that
         | out of the box automatically. What more do you need?
        
           | baskind wrote:
           | I have the same view of an app implemented with Rails+Turbo
           | and a duplicate in Elixir+LiveView.
           | 
           | Performance is comparable when I am close to the server
           | (elixir is slightly faster), but when on another continent
           | any content changes/navigation over websockets suddenly feel
           | very laggy, while navigation over HTTP in the supposedly
           | slower Ruby+Rails is actually consistently fast.
           | 
           | I've only recently discovered this as I went travelling to
           | another continent, so will do more perf testing.
           | 
           | But the nature of the always-connected websockets hasn't been
           | a pleasurable one for me: for instance, a LiveView process
           | crashes and you lose all the data in a big form, unless you
           | write glue code for it to restore. And the experience of
           | seeing the topbar getting stuck in the loading state the
           | second your internet connection is spotty or if you are
           | offline just gives me anxiety as a user.
        
       | jmull wrote:
       | I guess it's fun to build things, but this mashup is pretty
       | messy.
       | 
       | If you like Svelte (I do) you're probably going to find sveltekit
       | to be a lot simpler and more useful.
        
         | amsterdorn wrote:
         | +1, SPA should only be used as a last resort, not sure why the
         | article compares only to it.
         | 
         | SvelteKit is much simpler and well-documented and addresses the
         | issues mentioned.
        
       | peterisdirsa wrote:
       | Is LiveView same as Vaadin in Java world?
        
         | cess11 wrote:
         | Not really, Vaadin is mainly a UI component lib and some
         | convenience annotations, while LiveView is designed to allow
         | soft-realtime UI views over WebSocket.
        
       | stsrki wrote:
       | Essentially, it works the same as Blazor Server. Or am I wrong?
        
       | debussyman wrote:
       | I love LiveView + Svelte!
       | 
       | (I gave the talk at ElixirConf 2022 on how to combine them, but
       | the live_svelte contributors have done the work to make it a
       | reality)
       | 
       | IMO there is always a need for client side state, especially for
       | apps with rich UX. I also live in NYC where network connectivity
       | is not a given, especially in transit.
       | 
       | One super powerful feature that the authors don't cover is being
       | able to use Phoenix's pubsub, so that server-side state changes
       | that occur on other servers also get pushed reactively to any
       | client. It's pretty typical to have multiple web servers for
       | handling mid/high levels of traffic.
        
         | logicallee wrote:
         | How usable are LiveView pages while offline? (Due to
         | intermittent lack of network connectivity.)
        
           | victorbjorklund wrote:
           | Liveview does not work at all while offline. If you just
           | experience a short temporary drop it can reconnect you
           | automatically.
        
           | POiNTx wrote:
           | Out of the box, they don't work offline. But there's recently
           | been a project showing it's possible to create a PWA with
           | CRDT's and LiveSvelte:
           | 
           | https://github.com/tonydangblog/liveview-svelte-pwa
        
           | realusername wrote:
           | It's the same as any other web page, it doesn't work when you
           | receive or send data from the server.
           | 
           | Liveview isn't that special, the liveview paradigm works best
           | for what would already be online actions in a normal page.
        
         | matlin wrote:
         | Mobile networks in general also produce a lot of latency and
         | often warrants a local first caching system on the client. If
         | you want a LiveView like user experience but resilience to
         | flaky network conditions, we just added Svelte 5 bindings to
         | Triplit[1] which let's you write queries client-side and have
         | them sync with a server over web-sockets. Probably not
         | attractive to Elixir devs but if Svelte is your central focus,
         | Triplit is a good option.
         | 
         | [1] https://www.triplit.dev/docs/frameworks/svelte
        
       | fizx wrote:
       | > There is a (literal) speed of light limitation with this
       | approach: your server can only be so close to your users.
       | 
       | The next step is to compile your server to WebAssembly and ship
       | it to your clients. You can then use it to optimistically render
       | responses while waiting for the real server to return.
       | 
       | Sounds a little crazy, but we've actually pulled it off for a
       | project, and its magic.
        
         | CSSer wrote:
         | Wow, that sounds cool! Can you share any more details?
        
         | kevinak wrote:
         | Why wouldn't you just use a Service Worker for this?
        
           | AirMax98 wrote:
           | There's a couple different ways to skin this cat, but
           | WebAssembly is definitely the "coolest". I'd imagine even a
           | Service Worker is overkill compared to just inlining an
           | optimistic response in whatever rest client you're using.
           | 
           | Kind of similar to the content of this article, I wish people
           | were more upfront with their reasoning. Doing something
           | because "it's rad" is definitely fine by me!
        
             | ffsm8 wrote:
             | > _WebAssembly is definitely the "coolest"_
             | 
             | As always: when I doubt, it was likely because of CV-driven
             | development
        
             | kevinak wrote:
             | I just mutate the data object when using SvelteKit.
             | Blasphemy, I know. But it works, and it works well. :P
        
         | postalrat wrote:
         | It sounds over-engineered. Lots of over-engineered stuff gets
         | pulled off for no good reason.
        
           | paulgb wrote:
           | There is a good reason: it becomes _much_ easier to think
           | about state transitions, because optimistic and "verified"
           | updates both follow the same code path.
           | 
           | I've built a turn-based game that worked this way, where
           | essentially every player and the server contains a copy of
           | the same state machine, and the server determines the order
           | of state updates. Like OP said, once you have the framework
           | in place, it's magic.
        
           | thibaut_barrere wrote:
           | It's over-engineered unless done properly, it which case it
           | becomes a detail. I wouldn't be surprised to see some
           | automatic conversion of server-side code to front-end by
           | LiveView in the future for events where this behaviour is
           | applicable, actually!
        
         | knallfrosch wrote:
         | Wait, what's the difference to a fat client then?
        
           | riskable wrote:
           | Ease of distribution.
        
         | tyre wrote:
         | What about persistence? To me that's the main purpose of the
         | backend and running a server on the client doesn't fix that.
         | You still have the network latency of persistence, which is the
         | ultimate server state that should win.
        
         | willsmith72 wrote:
         | local-first with a client-side sqlite db sounds way simpler for
         | what seems like the same purpose
        
         | bogwog wrote:
         | That sounds a lot like the "client side prediction" that modern
         | multiplayer games do.
        
       | digdugdirk wrote:
       | For someone not in the web dev space, this looks like an
       | interesting way to get started.
       | 
       | If one has Python and Rust experience, what would be a
       | recommended "first principles" path to get started in
       | understanding web development with LiveView and Svelte?
        
         | kevinak wrote:
         | Start with Phoenix and add live_svelte when you need to. No
         | need to juggle both at the same time when you're starting out.
        
         | dinkleberg wrote:
         | I would advise against that path (unless you're looking at a
         | long time horizon). Phoenix is great, and it makes a lot of
         | really hard things simple, it also introduces you to a lot of
         | things that don't exist anywhere else (relies heavily on OTP).
         | 
         | But then that approach has almost nothing to do with svelte or
         | any other SPA tool so that is something else you'd have to
         | learn.
         | 
         | Personally I'd start with either Phoenix and avoid any SPA
         | tools until you get really comfortable and have hit the
         | boundaries of what is possible with Phoenix. Or alternatively,
         | I'd start with sveltekit and not think about Phoenix and save
         | exploring that for another time.
         | 
         | Phoenix is super cool, but I'd suggest starting with SvelteKit,
         | as you can build full stack apps and the same principles apply
         | if you want to move to react or vue or anything else.
        
       | todotask wrote:
       | I wonder what happened when attempting to open this website, as
       | it caused my Firefox browser to hang. I've never experienced such
       | a problem before.
        
       | enraged_camel wrote:
       | The biggest benefit to this would be gaining access to all the UI
       | component libraries in the JavaScript ecosystem. The lack of such
       | components in LV is one of the things that slows us down the
       | most.
        
       | furyofantares wrote:
       | A pattern sometimes used in multiplayer video games is there's a
       | bunch of code that is by default run on both the client and the
       | server. The client code runs as a prediction of the server state.
       | When the server state is received it slams the client state.
       | 
       | For games "prediction" is an apt description of this, because the
       | client can make a good guess as to the result of their input, but
       | can't know for sure since they don't know the other players'
       | inputs. But this paradigm can also be used to simply respond
       | immediately to client input while waiting for the official server
       | state - say by enabling/disabling a dropdown, or showing a
       | loading spinner.
       | 
       | There's also plenty of client state that's not run on the server
       | at all. Particle systems, ragdolls - stuff that doesn't need to
       | be exactly the same on all clients and doesn't interact with
       | other player inputs / physics.
       | 
       | If we're gonna have a persistent server connection I don't see a
       | reason this wouldn't work in a reactive paradigm.
        
         | POiNTx wrote:
         | That's what I did with: https://territoriez.io/
         | 
         | It's a clone of https://generals.io/
         | 
         | It's built with LiveSvelte. It doesn't need any predictive
         | features as it's basically a board game and runs at 2 ticks per
         | second. It does use optimistic updates to show game state
         | before it actually updates on the server. The server overrides
         | the game state if they're not in sync.
         | 
         | All game logic is done inside Elixir. To do predictive
         | correctly, you'd need to share logic between the server and the
         | client. Otherwise you're writing your logic twice and that's
         | just a recipe for disaster.
         | 
         | One possible solution which I didn't investigate, but should
         | work, is to write all game logic in gleam (https://gleam.run/).
         | Gleam is compatible with Elixir, AND it also can compile to js,
         | so you could in theory run the same code on the server and the
         | client.
         | 
         | Now this is a big mess to understand, you could say "why don't
         | write it all in js and be done with it" and you'd make a very
         | good point and I'd probably agree. The main advantage you get
         | is that you can use the BEAM and all it's very nice features,
         | especially when it comes to real time distributed systems. It's
         | perfect for multiplayer games, as long as you don't take into
         | account the frontend :)
        
           | djbberko42 wrote:
           | As someone who started using Elixir this year (for work) this
           | is really cool. I have had some ideas for some SPAs and games
           | just like these io ones and it'd be great to use Elixir for
           | them. Do you think a top down fps io game would be plausible
           | with this setup? There would need to be at least 60 ticks per
           | second I'd think.
        
             | POiNTx wrote:
             | Definitely possible. Tick rate isn't the problem, Elixir is
             | very performant. Just the predictive elements are an issue
             | if you're working with 2 different languages. I'd go with
             | Gleam from the start and look into compiling to js.
        
               | spiderice wrote:
               | Don't you lose a lot of the niceties of Elixir when
               | switching to Gleam, just because Gleam is a younger
               | project? LiveView would be the big one I'm thinking of.
               | Do you see that as a worthy trade?
        
               | POiNTx wrote:
               | You can still use LiveView/Phoenix/Elixir, but have your
               | game logic be in Gleam. I haven't used it though so I
               | could be wrong here.
               | 
               | A little bit more about it here:
               | https://katafrakt.me/2021/10/13/app-with-elixir-business-
               | log...
               | 
               | You'd call Gleam code like this inside Elixir:
               | 
               | `:game.move(game, player_1, :left)`
               | 
               | And you'd receive an Elixir map `%Game{}` which you can
               | then use in LiveView. If that makes sense.
        
               | buzzerbetrayed wrote:
               | Cool! I'm going to have to look more into Gleam. I saw it
               | hit v1.0.0 on ElixirForum last month, but I figured it
               | was an alternative to Elixir rather than something that
               | played so nicely with it.
        
           | rytill wrote:
           | Hey, about your clone of https://generals.io - why not make
           | it a better designed version of that game instead of just a
           | clone? Perhaps you have plans to. There are things about the
           | original that kind of suck.
           | 
           | 1) Spawning closer to the center is just strictly
           | significantly worse, corners are best. It's essentially an
           | auto-lose to spawn anywhere but an edge or corner in a FFA.
           | 
           | 2) Getting literally all of someone's armies when you kill
           | them is so good that it pushes players to just try to all-in
           | the first person they meet every single time. There is no way
           | to "fast expand" once you've met another player because of
           | the first factor, and also that 40-50 armies on a neutral
           | castle is very high. I think the "early-game" can be much
           | better designed.
           | 
           | 3) Perhaps you should be able to change your capital, which
           | could solve problem 1.
           | 
           | 4) There are many ways you could keep the simplicity of play,
           | but boost the richness and depth of the actual gameplay. For
           | instance, more chokepoints that would allow actual strategic
           | use of territory and army positioning. Different tiles which
           | have different advantages to owning. Borrowing from something
           | like civ - forests or hills which have a defensive boost when
           | you're inside. Rivers which attacking across is
           | disadvantageous.
           | 
           | Just some feedback from someone who enjoys games like Chess
           | and Starcraft, and thinks the core gameplay loop of
           | generals.io is really fun, but believes that it is seriously
           | lacking in strategic depth.
        
             | POiNTx wrote:
             | It's a little bit different from generals.io but the points
             | you mention are very valid. I originally started working on
             | it as a showcase of LiveSvelte + I like generals.io a lot
             | and thought it could be improved visually + UX wise. Then
             | afterwards started thinking a bit about the game design and
             | what I could improve, but eventually burned out on the
             | project. Was also at a time when I wasn't working but am
             | working again.
             | 
             | Maybe I'll pick it up at some point, but also open to other
             | people working on it if they're interested. I'd be open to
             | partner up with someone to eventually make it monetized.
             | It's not open source as I wanted to add paid features
             | (cosmetic features, not pay to win).
             | 
             | A solution for most of these issues is a modifier system. I
             | have a basic one in place and wanted to experiment with
             | different modifiers. A modifier can be anything, like
             | prevent spawning in the center, to increasing rewards for
             | capturing cities, to even allow crossing the border of the
             | map into the other side, like pacman (which could address
             | point 1). Then the goal would be to see which modifiers
             | stick with the player base, and make them the default,
             | while still allowing for custom games with different
             | modifiers. Generals has a similar system in place and they
             | sometimes make the modifier the default for the day, which
             | I like a lot.
        
           | ElFitz wrote:
           | > To do predictive correctly, you'd need to share logic
           | between the server and the client. > > One possible solution
           | [...] is to write all game logic in gleam [...]
           | 
           | Rust, with Uniffi, can also be a good candidate. You'd be
           | targeting WebAssembly.
        
         | dkersten wrote:
         | Isn't that just optimistic updates? This has been common in
         | client side logic for a long time, no?
        
           | furyofantares wrote:
           | I was more talking about the method to achieve optimistic
           | updates, rather than the concept of optimistic updates in
           | general. That is, having the client and server code be
           | identical where applicable, with client code being run in a
           | prediction context.
           | 
           | I'm not a web expert but the optimistic updates I've seen in
           | web stuff is more like, I'm gonna fetch this url and here's
           | the data I expect back. Nothing wrong with that, but it's
           | achieved in a different way, where the server is all about
           | providing data and the client is all about managing state.
           | 
           | The OP is talking about maintaining a persistent connection
           | to a server which is doing most of the state management. They
           | detail things this does well (makes the server easier to
           | write) and things it does poorly (makes optimistic updates
           | harder) and a solution to the things it does poorly. So I'm
           | drawing a parallel to other systems where state is managed on
           | the server and must be predicted on the client.
        
             | mb7733 wrote:
             | Haven't used it in years, but Meteor.js worked like this.
             | Even to the point where it had a client-side database
             | implementation that mirrored (parts of) the server-side
             | database.
             | 
             | It would apply the updates optimistically to the client
             | side DB, and the much of code that sat between the database
             | could be shared between client and server. Neat stuff, even
             | if overall Meteor wasn't my favourite thing to work with.
        
         | OJFord wrote:
         | You need to be smart about this though, I don't want it to look
         | like a live/interactive form has worked for example - updating
         | derived data on the page - if it's then going to turn out that
         | actually the server had an error or there was network trouble,
         | and it all gets undone (or worse I close the page/navigate away
         | not realising at all).
        
           | willsmith72 wrote:
           | you would be in the minority then, most people these days
           | want (and expect) live feedback if the action's result is
           | predictable enough
           | 
           | e.g. throttle your network and upvote a hn comment. you're
           | not sitting there waiting with a spinner while the server
           | responds, it's all in the background.
           | 
           | the hn implementation isn't great though - if the upvote
           | request fails, the optimistic update isn't rolled back, and
           | you have no knowledge that it failed. for hn, who cares, it's
           | just a lost upvote, but for most modern web apps you would
           | show the user that the action failed
        
             | OJFord wrote:
             | If you're (would be) 'sitting there waiting with a spinner'
             | then that endpoint is too slow, regardless of what the
             | frontend does in the meantime.
        
               | willsmith72 wrote:
               | depends on the definition of "slow". unless you have
               | servers and databases everywhere (overkill for 99% of
               | apps), your endpoint will be probably be >400ms for some
               | people somewhere, enough to feel as a user.
               | 
               | that's without accounting for patchy reception (in a
               | tunnel?), network blips, server blips (overworked?), etc.
               | 
               | i'm not saying everything should be optimistic, but for
               | something like a hn upvote, i dont care if my public wifi
               | freaked out and took 3 seconds for that 1 request, and i
               | think more people are like that than not
        
         | pests wrote:
         | As a player of a game (Overwatch) that simulates ragdoll
         | physics locally and non-deterministic, I wish they did it
         | correctly.
         | 
         | What ends up happening is someone dies and their body flies off
         | or gets stuck in a hilarious pose... and no one else saw it,
         | nor can you rewatch it in the replays as every client renders
         | it differently.
         | 
         | Unless you catch it with a live recording then it's lost
         | forever. With a sometimes goofy game like Overwatch it's sad
         | knowing no one else is seeing it.
        
           | wldcordeiro wrote:
           | In Counter Strike I've seen it be an actual issue too where a
           | player's view is blocked by a body and their teammates don't
           | have the same issue while spectating them.
        
       | jonnycat wrote:
       | This is great. LiveView is truly amazing and greatly speeds up
       | development, but as the post describes, there are a couple of
       | rough edges. They're all solvable, but sometimes there aren't
       | clear or well-established patterns for how, so it can feel a bit
       | ad hoc. While I'm not currently using Svelte for this kind of
       | thing, I'm really glad to see people formalizing some of the
       | issues + solutions.
        
         | atonse wrote:
         | My main complaint with LiveView is communication between
         | components in a tree (like callbacks and sending data back).
         | It's still janky at a core syntax level between send, send
         | update, etc. I feel this is something only the core team can
         | fix because it probably requires some kind of use of macros
         | etc.
        
       | krainboltgreene wrote:
       | My own company has found significant advantage by using LiveView
       | with Alpine, specifically in CSP mode since we can't allow `eval`
       | to happen on the client. When I originally looked at LiveSvelte
       | it seemed very new and untested. It also had some unsolved
       | implications in strict CSP environments. Glad to see that it's
       | become very useful!
       | 
       | Our own pattern (LiveAlpine?) is as follows:
       | 
       | Does the component need HTML? Then use an HTML Component. Does
       | the component have server-side state? Then use a Live Component.
       | Does the component need client-side behavior and/or state? Then
       | also define an Alpine component. Does the component need to
       | receive client-side events from the server or make HTTP requests?
       | Then also define a Phoenix Hook.
        
         | scop wrote:
         | Thank you for providing your pattern.
        
       | kimi wrote:
       | > What's most game-changing, though, is that you have a backend,
       | stateful process that is collaborating with a frontend, stateful
       | process.
       | 
       | ...given that managing state is the thorniest of issues, what
       | could go wrong with this approach?
        
       | matt_s wrote:
       | > LiveView makes a lot of things easy. But it also makes some
       | easy things hard.
       | 
       | Having been involved with web applications for a couple decades
       | there were some weird things LiveView did that weren't easy for
       | me to pick up. Maybe its changed in the last 12-18 months but
       | initial versions were built odd for some seemingly easy types of
       | XHR things one would want to do.
        
       | moomoo11 wrote:
       | Anyone else use this in production with a significant user base
       | or business usage? How's ur experience?
        
       | sebastianconcpt wrote:
       | Have you guys considered htmx before going that way? If you can
       | share pro/cons I'd love to hear.
        
       | lacoolj wrote:
       | When I watch people using Nextjs, it makes me cringe. "This is
       | just PHP but less clear what happens where"
       | 
       | And yet for some reason the thought of Phoenix + LiveView +
       | Svelte makes me want so badly to try it. Just the thought of
       | playing with it has me giddy. This must be a mental disorder I'm
       | experiencing.
       | 
       | Dissociative Framework Disorder.
        
       | inopinatus wrote:
       | > If a new row comes in, you just need to push it to your table,
       | and LiveView will update the client for you.
       | 
       | Don't do this in line-of-business apps where those rows are
       | interactive. The cognitive latency readily induces users into
       | clicking the wrong thing, emailing the wrong customer, refunding
       | the wrong transaction etc. My preferred UX instead is a sticky
       | banner conveying "the data has changed, click here to refresh".
       | Or, in a pinch, ensure that new rows are rendered append-only
       | with no change in scroll position.
        
         | EmilStenstrom wrote:
         | This CAN work, if you animate in the new lines slowly and
         | (maybe) disable clicks while new data is coming in.
        
       | gardenhedge wrote:
       | Article misses a comparison to newer frameworks like Remix which
       | are server side driven
        
       ___________________________________________________________________
       (page generated 2024-04-03 23:01 UTC)