I'm very glad to see the work, thank you for all of the efforts.
HN user
bcardarella
CEO of DockYard.com
Twitter: @bcardarella GitHub: bcardarella
I wonder how much this work being pushed forward right now is a response to the Bun drama.
Phantasy Star remains to this day my favorite RPG. I was the kid in the neighborhood who's parents bought a SEGA Master System instead of a NES. I would play Final Fantasy a bit over their houses but it always paled in comparison to Phantasy Star. I recently replayed it on Nintendo Switch. Still a very challenging RPG and stil feels great.
I agree that borrowing against unrealized gains is crap, it's lead to major economic divide. However, just make borrowing against unrealized gains illegal. Taxing unrealized gains is the wrong solution for a real problem.
"written in Rust"
ok
I only ran both with `cargo build --release`
Just a small comparison, compiled for release:
Boa: 23M Brimstone: 6.3M
I don't know if closing the gap on features with Boa and hardening for production use will also bloat the compilation size. Regardless, for passing 97% of the spec at this size is pretty impressive.
One that was tossed in 0.15 was `usingnamespace` which was a bit rough to refactor away from.
You may be correct, but the rate of change in baseball is glacially slow compared to the other sports. One of baseball's intrinsic values is it's legacy, tradition, and history. Some may scoff at that, and I think there are good arguments against legacy/tradition as a reason to withhold change, but there are a lot of people out there that believe this. The MLB Commissioner's have largely been tasked with protecting that tradition and history.
This is how CSS should be written. I will never understand why class names need to repeat the semantic purpose for a given element.
How far should I be able to progress? I can out of the first room and open the cabinet in the second room, but cannot progress further.
Epic paintball venues
The issue in this case was Opus was pretty crap at C. It kept introducing segfaults.
I tried to do this a few weeks ago, I tried to build a NIF around an existing C lib. I was using Claude Opus and burned over $300 (I didn't have Pro) on tokens with no usable results.
This is another extraction from the project that I discussed in this HN thread: https://news.ycombinator.com/item?id=44651539#44652356
tldr; we're building a headless browser in Elixir that will embed on device, communicate to the native 1st class rendering engine (i.e. SwiftUI, Jetpack Compose, WinUI3, etc...) via disterl, and allow for web-like ergonomics to build truly native SSR applications.
The README for Elixir Pack is a bit focused on the LiveView Native project but that documentation will soon be updated to remove mention of it.
Increased submission quantity and quality
So everybody just LLM'd this, right?
How does the performance compare to projects like Wasmtime?
This is one of the fundamental differences for what we're doing. We are not building a write-once-run-everywhere solution. SwiftUI will have its own templates, Jetpack (Android) will have its templates, WinUI3 will have its templates.
Apple also doesn't allow JITs, and you cannot hot load code to modify the application.
The LVN Elixir libraries are pretty much done and those really shouldn't change out side of perhaps additional documentation. I have been back and forth on the 2-arity function components that we introduced. I may change that back to 1-arity and move over to annotating the function similar to what function components already support. That 2-arity change was introduced in the current Release Candidate so we're not locked in on API yet.
What is changing is how the client libraries are built. I mentioned in another comment that we're building a headless web browser, if you haven't read it I'd recommend it as it gives a lot of detail on what we're attempting to do. Right now we've more or less validated every part with the exception of the overall render performance. This effort replaces LVN Core which was built in Rust. The Rust effort used UniFFI to message pass to the SwiftUI client. Boot time was also almost instant. With The Elixir browser we will have more overhead. Boot time is slower and I believe disterl could carry over overhead than UniFFI bindings. However, the question will come down to if that overhead is significant or not. I know it will be slower, but if the overall render time is still performant then we're good.
The other issue we ran into was when we started implementing more complex LiveView things like Live Components. While LVN Core has worked very well its implementation I believe was incorrect. It had passed through four developers and was originally only intended to be a template parser. It grew with how we were figuring out what the best path forward should be. And sometimes that path meant backing up and ditching some tech we built that was a dead end for us. Refactoring LVN Core into a browser I felt was going to take more time than doing it in Elixir. I built the first implementation in about a week but the past few months has been spent on building GenDOM. That may still take over a year but we're prioritizing the DOM API that LiveView, Hotwire, and Livewire will require. Then the other 99% of DOM API will be a grind.
But to your original point, going the route of the browser implementation means we are no longer locked into LiveView as we should be able to support any web client that does similar server/client side interactivity. This means our focus will be no longer on LiveView Native individually but ensuring that the browser itself is stable and can run the API necessary for any JS built client to run on.
I don't think we'd get to 100% compatibility with LiveView itself without doing this.
You'd have to refer to all of the applications running on the BEAM that are distributed across multiple datacenters. Fly.io's entire business model is predicated on globally distributing your application using the BEAM. I'm not sure what that book said exactly perhaps the original intent was local distribution but Erlang has been around for over 30 years at this point. What it's evolved into today is architecturally unique compared to any other language stack and is built for global distribution with performance at scale.
Not sure as I haven't done any work with it. On a cursory glance it could have some overlap but it appears to not target the 1st class UI frameworks. It looks to be a UI framework unto itself. So more of a Flutter than what we're doing is my very quick guess. We get major benefits from targeting the 1st class UI frameworks, primarily being we let them do the work. Developing a UI native framework I think is way way more effort than what we've done so we let Apple, Google, and Microsoft to decide what the desired user experience is on their devices. And we just allow our composable markup to represent those frameworks. A recent example of this is with the new "glass" iOS 26 UI update. We had our client updated for the iOS 26 beta on day 1 of its release. Flutter has to re-write their entire UI framework if they want to adapt to this experience.
XAML will be a target as we intend to build a WinUI3 client. Of the big three native targets: Apple, Android, Windows the later may be the easiest as from what I've seen nearly everything is in the template already
As far as how it is different from React Native. That's a good question, one that I think is worth recognizing the irony which is that, as I understand it, without React Native our project probably wouldn't exist. From what I understand RN proved that composable UI was the desired UX even on native. Prior to RN we had UIKit and whatever Android had. RN came along and now we have SwiftUI and Jetpack Compose, both composable UI frameworks. We can represent any composable UI frameworks as a markup, not so much with the prior UI frameworks on native, at least not without defining our own abstraction above them.
As far as the differentiator: backend. If you're sold on client-side development then I don't think our solution is for you. If however you value SSR and want a balnance between front end and backend that's our market. So for a Hotwire app you could have a Rails app deployed that can accept a "ACCEPT application/swiftui" and we can send the proper template to the client. Just like the browser we parse and build the DOM and insantiate the Views in the native client. There are already countless examples of SSR native apps in the AppStore. As long as we aren't shipping code it's OK, which we're not. Just markup that represents UI state. The state would be managed on the server.
Another areas we differ is that we target the native UI framework, we don't have a unified UI framework. So you will need to know HTML - web, SwiftUI - iOS, Jetpack Compose - Android. This is necessary to establish the primitives that we can hopefully get to the point to build on top of to create a unified UI framework (or maybe someone solves that for us?)
With our wasm compilation, we may even be able to compile React itself and have it emit native templates. No idea if that would work or not. The limits come when the JS library itself is enforcing HTML constraints that we don't observe, like case sensitive tag names and attributes.
What about offline mode? Well for use cases that don't require it you're all set. We have lifecycle templates that ship on device for different app states, like being offline. If you want offline we have a concept that we haven't implemented yet. For Elixir we can just ship a version of the LV server on device that works locally then just does a datasync.
That's correct, but we can make changes to the views at runtime and these merge into the SwiftUI viewtree. That part has been working for years. As far as how we take the document and convert to SwiftUI views, there is no reflection in Swift or runtime eval. The solution is pretty simple: dictionary. We just have the tag name of an element mapped to the View struct. Same with modifiers.
We're delivering LVN as I've promised the Elixir community this for years, from LVN's perspective nothing really changes. We hit real issues when trying to support live components and nested liveviews, if you were to look at the liveview.js client code those two features make significant use of the DOM API as they're doing significant tree manipulation. For the duration of this project we've been circling the drain on building a browser and about three months ago I decided that the just had to go all the way.
https://github.com/otp-interop/elixir_pack
we compile without the JIT so we can satisfy the AppStore requirements
I hate to say this but usually when I hear that people have problems making Erlang/Elixir fast it comes down to a skill issue. Too often devs explore coming from another language and implement code as they would from that other language in Elixir and then see it's not performant. When we've dug into these issues we usually find misunderstandings on how to properly architect Elixir apps to avoid blocking and making as much use of distribution as possible.
* The working name of the browser is Crane: https://github.com/liveview-native/crane/tree/ios
* our vDOM: https://github.com/liveview-native/gen_dom
* selector parsing: https://github.com/liveview-native/selector
* compile Elixir to ios: https://github.com/otp-interop/elixir_pack
I'm involved with this project and wanted to provide some context. This is an extraction for a much larger effort where we're building a web browser that can render native UI. Think instead of:
`<div>Hello, world!!</div>`
we can do:
`<Text>Hello, world!</Text>`
I want to be clear: this is not a web renderer. We are not rendering HTML. We're rendering actual native UI. So the above in SwiftUI becomes:
`Text("Hello, world!")`
And yes we support modifiers via a stylesheet system, events, custom view registration, and really everything that you would normally be doing it all in Swift.
Where this library comes into play: the headless browser is being built in Elixir to run on device. We communicate with the SwiftUI renderer via disterl. We've built a virtual DOM where each node in the vDOM will have its own Erlang process. (I can get into process limit for DOMs if people want to) The Document will communicate the process directly to the corresponding SwiftUI view.
We've taken this a step further by actually compiling client-side JS libs to WASM and running them in our headless browser and bridging back to Elixir with WasmEx. If this works we'll be able to bring the development ergonomics of the Web to every native platform that has a composable UI framework. So think of actual native targets for Hotwire, LiveWire, etc...
We can currently build for nearly all SwiftUI targets: MacOS, iPhone, iPad, Apple Vision Pro, AppleTV. Watch is the odd duck out because it lacks on-device networking that we require for this library.
This originally started as the LiveView Native project but due to some difficulties collaborating with the upstream project we've decided to broaden our scope.
Swift's portability means we should be able to bring this to other languages as well.
We're nearing the point of integration where we can benchmark and validate this effort.
Happy to answer any questions!