Is Servo ready if I want to play around with it in a embedded-browser capacity? Say I wanted to have some basic HTML+CSS UI, can I create a Rust binary that embeds Servo+those resources and it kind of works?
It pulls in Servo/Firefox's CSS engine Stylo (and Servo's HTML parser html5ever) and pairs it with our own layout engine (which we are implementing mostly as libraries: Taffy [0] for box-level layout and Parley [1] for text/inline layout) and DOM implementation. Rendering and networking are abstracted behind traits (with default implementations available) and you can drive it using your own event loop.
Minimal binary sizes are around 5mb (although more typical build would be more like 10-15mb).
would this be a good fit for rendering a game UI? showing various stat/dialogue displays, an inventory/equip screen with draggable items, menus, etc. All I really want is html+css to do styling and layout and I'd rather have the interaction logic in the game code than javascript anyway
I think it would, modulo that it's not really "ready" yet.
We do have a couple of PoC examples of integrating with the Bevy game engine. Both of these use Dioxus Native, which wraps Blitz with Dioxus (which is a React-like framework but in Rust rather than JavaScript - https://github.com/DioxusLabs/dioxus), but you could do DOM tree creation and event handling manually if you wanted to.
- This first one includes Bevy inside a window setup by Dioxus Native (using a `<canvas>` element similar to how you might on the web). Here the event loop is controled by Dioxus Native and the Bevy game is rendered to a texture which is then included in Blitz's scene. https://github.com/DioxusLabs/dioxus/tree/main/examples/10-i...
- This second one does it the other way around and embeds a Dioxus Native document inside a window setup by Bevy. Here the event loop is controlled by Bevy and the Blitz document is rendered to a texture with which Bevy can then do whatever it likes (generally you might just render it on top of the games, but someone tried mapping it into 3d space https://github.com/rectalogic/bevy_blitz) https://github.com/DioxusLabs/dioxus/tree/main/examples/10-i...
The latter is probably what I would recommended for game UI.
Both approaches probably need more work (and Blitz could do with more complete event handling support) before I would consider them "production ready".
You would end up simply with Electron 2.0. I tried de-entangling the Servo CSS / JS / Layout engine some years ago, to see if it would be more lightweight, it wasn't: https://github.com/fschutt/servo_gui_test (62 MB binary size, several hundred MB RAM usage IIRC)
I am currently working on getting https://azul.rs/reftest ready, which uses some of the underlying technologies as Servo (taffy-layout, webrender) but uses no JavaScript and also has a C / Python API. Azul is basically that, except it's not usable yet.
I know about Dioxus / Blitz, but it's a very, very different project. The only common part is that both Azul and Blitz use taffy for flexbox / grid, but both the technologies, architecture, funding and goals are extremely different:
Blitz:
- Custom renderer (Skia?) vs Azuls WebRender fork (to get rid of any C dependencies)
- Stylo (CSS parser) vs azul-css (to support compilation of CSS to const items)
- HarfRust (font shaping) - vs allsorts (I used allsorts also in printpdf, so it fits)
- Skrifa (font parsing) - vs allsorts again (simplifies things)
- Fontique (font selection) - vs rust-fontconfig (custom pure-Rust rewrite of fontconfig)
- Parley (line breaking) - vs Azuls text3 engine
- All as separate projects vs Azuls monorepo-style
Dioxus:
- RSX macros, data + function coupled together vs Azuls "C function callbacks + HTML dataset" model
- Binary hot-patching vs Azuls dynamic linking model
- Macros vs Azuls HTML/CSS to Rust/C compiler build tool (no macros)
- Funded by YC (not sure about upsell?) vs funded by donations (once it's stable enough) and my Maps4Print cartography startup (dogfooding)
These things matter, even for small decisions. For example, Azul uses a custom CSS parser because the CSSProperty is a C-compatible enum, so that later on you can compile your entire CSS to a const fn and use CSS strings without even doing any allocations. So even on that level, there's a technological-architectural difference between Azul and Stylo.
But the core point is more architecturally: Azuls architecture is built for de-coupling the user data from the function callbacks, because I see this as the Archilles heel that all GUI systems so far have failed at:
Dioxus however repeats this exact same pattern again, and even the Elm architecture doesn't really fix it. I didn't finish the document but basically there is a (1) "hierarchy of DOM elements" and a (2) "graph of UI data" and those two are not always the same - they can overlap, but the core assumption of many GUI toolkits is that (2) is a tree (it's a graph, really) and (2) is always in the same hierarchy as (1), which is why GUI programming is a pain, no matter what language / framework. Electron just makes the visual part easier, but then you still need React to deal with the pain of data model / view sync.
I can collaborate on the flex / grid solver ofc, but it's very hard to collaborate on anything else because the technologies used, the goals, the architecture, etc. are very different between Dioxus / Azul. Azul is more "monorepo-NIH integrated solution" (because I often got bug reports in 2019 that I couldn't fix because I didn't own the underlying crate, so I had to wait for the maintainers to do another release, etc. - I learned from that).
As a note, the layout engine is also now heavily vibe-coded (sorry not sorry), so I don't take credit - but feel free to take inspiration or copy code. Gemini says the solver3 code is a "textbook implementation", take that as you will. My idea was to build a "AI feedback loop" to semi-automatically put the HTML input, the debug messages (to see what code paths are hit), the source code and the final display list into a loop to let the AI auto-debug the layout engine. So that part of writing the HTML engine isn't really hard, assuming the plan works out. The hardest part is caching, scrolling, performance debugging, interactions between different systems, and especially supporting the C API. Layout is comparably simple.
- You don't have use Dioxus to use Blitz: you can do your own DOM construction and event handling with imperative Rust APIs.
- You don't have use any of the provided renderers to use blitz-dom (although our default renderer is Vello which is also pure Rust), and it would be possible to hook it up to WebRender.
- We have a lot of the tricky incremental layout and caching logic implemented (although there are still bugs).
- Blitz has grant funding through NLnet as well as funding from DioxusLabs, and is fully open source under permissive licenses (MIT/Apache 2.0) that don't really allow for "rug pulling".
---
That being said, the designs around CSS do sound quite different: we have chosen to take on a relatively heavy dependency in Stylo; we don't support non-tree-like structures; and in general, if you wish to do your own thing then that it what you ought to do!
Not sure that I agree that layout is simple (I have spent many long hours debugging the nuances of CSS layout over the past months), and I'm a little skeptical that an AI-based approach will work out. But I wish you luck!
Coming from someone who mainly does Vanilla JS, CSS, HTML (no frameworks) for their apps, your API looks very approachable. I like that you have Python bindings too. (Only thing better would be to take JavaScript, HTML and CSS.) I'll have to try it out sometime.
I tried it as a little preview window for writing my blog, which is (in my opinion) very basic HTML and CSS. Whole page rendered wrong, though I admit I didn't bother to find out why. Give it a shot, but keep your expectations low.
If you have a basic site that doesn't work you can open an issue on the repo. If you have some relatively simple site, its useful for the team to know what features that people are using are broken.