Show HN: Ultralight – Lightweight, Pure-GPU HTML UI Renderer for C++
ultralig.ht
ultralig.ht
>> We started over with WebKit, stripped it to the bare-minimum, then rebuilt it from scratch with an eye towards embedding.
This is very similar to the origin story of Flutter. [1] In the end Flutter team just abandoned the HTML based UI idea and went with their own component system. As per the podcast, the core team doesn't have any plans to bring Flutter to the desktop development. I wish they would do it, that way we can get a performant alternative to Electron.
[1] https://softwareengineeringdaily.com/wp-content/uploads/2018...
Edit: Found the actual quote from the podcast:
>> We allowed ourselves, I think it was a week or two and we just tore Chrome apart and see how fast we could move on our benchmarks. Allowing ourselves to break compatibility to the web. The end result was we were 20 times faster on some of the benchmarks that we cared about and obviously, the end product wasn’t the web, it didn’t render all web pages, but it taught us that there was a lot of potential to do things better, faster, if we worked on something that was beyond the web.
There's actually been several HTML UI projects that "break compatibility with the web" in varying degrees, with some breaking almost completely (eg, Sciter and libRocket) for the sake of simplicity and performance.
The goal of Ultralight was to see if we could strike a balance between modern HTML5 compatibility (eg, actually being able to render the Alexa Top 50) and reducing size and complexity for use in an embedded use-case.
I think we've struck a good balance so far but can go much farther. We plan to support much more of the web platform while still remaining small by use of shared modules (eg, for WebAudio/Video) so users can pick and choose how big of a distributable they want based on feature support.
As an aside, I took 2 years off just to explore if this was possible, partly funded by my previous work on Awesomium. This project is the result of that research and development.
Qt / QML is an existing performant alternative to Electron.
There are other ways to get the same juice, though.
I love MOAI, for the same reasons as I love Flutter. Except MOAI has a better license .. even if the responsibilities for using it as a non-Game GUI are pretty high. You can do it, but you've gotta have Lua-foo.
In my case, I'm going to glom Ultralig.ht onto MOAI some day soon, and see if it makes the Flutter desktop problem irrelevant...
The team was lead by IE devs, which were trying to create a design how would it look like if the browser was actually designed for applications and not documents.
Also for those that aren't aware the initial design of CSS grid was based on how XAML grid layouts work.
Netsurf is on other hand is an opposite:
Css parsing - separate lib
Html/xhtml parsing - separate libs
Network - fully based on external libs
Js execution - separate lib
Dom - separate lib
Layouting - separate lib
Final renderer - separate lib
It has a lot of promise
That anybody would -- or could -- dig in, tear it apart, and try to make something better... That is impressive and I salute you.
Edited to add: I am however only interested in using open source applications on Linux, so I'm out on this one, unfortunately. That's not strictly true -- for example, I use ST3 as my daily driver -- but I've got to see a substantial value proposition to weight my decision towards becoming a user. Still, impressive nonetheless, and best of luck to you in this endeavor!
I also like how there are at least five string classes (to be fair, there are good reasons for most of them): String, AtomicString, StringImpl, CString, WebString.
Edit: If you're feeling particularly brave, look up some of the text-run and unicode bidi algorithm related code. I don't remember how old that code is, but some of the darker corners of WebKit go back literally decades.
Q: Who is behind Ultralight?
A: Hi, I'm Adam Simmons...
YES that is what I am talking about! I hate it when people try to hide behind a company name. When they try to make it out like they're some big "proper" business. Just tell me who you are, and I'll trust you much more. Just like this. Thank you very much Adam!- What does it do to be better (smaller, more memory-efficient) than a browser engine? Which features does one lose?
- When will Linux support ship? (Edit: I see it's planned, this was just an assumption before)
- There could be bindings to other languages in the future, right? (Edit: I see .NET compatibility is planned)
Edit: - Where's the source? Yes, this is a rethorical question; What is the motivation to keep it closed? This will probably hinder adoption (unless support is damn good).
- Could you upload the files to GitHub (or some other, similar place)? It's probably less intimidating than "Get SDK" and a lot nicer to browse through samples on my phone (Chrome doesn't seem to forward zips to apps at all, I don't really have a good text/code viewer installed etc).
Pros (Ultralight is...)
- Smaller distributable (25% the size of Electron/CEF or smaller).
- Simpler and easier to build (fewer dependencies and smaller codebase).
- More configurable (users can do custom handling of file system, fonts, GPU rendering, clipboard, and more).
- Potentially more performant (all rendering is done via GPU command buffers).
- First-class support from an actual company.
Cons:
- No support for MathML, Geolocation, WebGL, IndexedDB, WebAudio/Video (for now)
- Less mature and unstable.
- Slower release cycle (might be a pro).
Linux support is planned and will ship when it's ready, you can track its progress here: [1]
Yes, we have plans to publish a C API interface to simplify bindings for other languages.
The WebCore source is available here [2]. The rest of the source is kept closed for now to keep our licensing/support options open. There's a chance we will find a better funding model and will open-source the entire repo in the future.
Yes, I agree the SDK packages should belong on GitHub, and will also be BSD'ing the framework/sample code so users can fork and hack on it at will.
Slower deprecation cycle is a pro.
> the API is currently available for C++ only and requires Direct3D 11 on Windows and Metal on macOS.
“Embedders” here seems to mean “people who want to embed a web UI in a desktop application.” This confused me at first because I wondered why an embedded systems UI framework only supported Windows and macOS instead of Windows and small Unixes.
I think you should open source Awesomium also, allowing contributors to maintain it.
To the creator: Could you help me understand how lightweight this is, in terms of memory usage? For instance, how much memory is used to render the Wikipedia sample page, when using Ultralight, vs. using a single Chrome browser tab to do the same?
Thanks!
Currently, the memory usage is similar or less than that of Chrome/Safari, with most memory being allocated by the JavaScriptCore VM, render geometry pools, and some by the GPU texture atlas.
So far, we've managed to reduce the total binary size to about 25% of a similar Electron-based app by reducing dependencies to the bare minimum and punting platform features to be handled by the embedder instead. See our Platform API [1].
As far as runtime memory usage goes, a lot of that memory is being allocated by pools and cache structures to improve performance (the same is true in most browsers). We will be implementing a memory management API soon so that this behavior can be configured (offering users the ability to strike a balance between memory usage and performance).
Additionally, Ultralight is NOT multi-process. The overhead of tens to nearly a hundred renderer processes makes sense for sandboxing in a browser situation but not for HTML UI where the assets are controlled by the user and security is less of a concern.
- [1] https://github.com/ultralight-ux/ultralight-0.9-api/tree/mas...
Real life HTML UI requires a bit more than standard HTML/CSS.
At some point you will discover that you will need something like this:
elem.popup(popupElem, at)
to show arbitrary DOM elements as popup elements (DOM-element-in-its-own-window) like here https://terrainformatica.com/w3/sciter-tooltip.pngYet pure HTML desktop windows: https://sciter.com/html-window/ with support of Acrylic/Vibrancy: https://sciter.com/sciter-4-2-support-of-acrylic-theming/
And at some point you may discover that by adding this to CSS:
div.widget {
prototype: MyWidget url(/js/widgets.js);
}
and extending DOM Element by simple elem.merge(newHtml[, callback])
you will have the whole ReactJs thing obsolete/not-needed.All that ...
If you want you can contact me so we can discuss all these in details.
If I'm writing a green-field HTML5 app, and I don't derive any benefit from Javascript, is the interface between Ultralight and JavaScriptCore clean enough to just rip out the JS support altogether, replacing it with something simpler?
I'm picturing:
1. I embed Ultralight into a process that exposes a simple script-loading API, ala the one in JSCore;
2. I write HTML with no <script> elements, just elements with onclick/ontouch/etc. handler attrs, where these handlers just contain a UUID;
3. Ultralight passes the "script code" (i.e. the UUID) to my trivial script-loading API, which simply looks up a native handler based on the provided UUID, and returns its function pointer;
4. Ultralight holds onto that function pointer and treats it just like a regular thunkable Javascript handler function pointer.
In other words, all the "dynamism" of the HTML would be handled by native, static code in my compiled binary, with the only thing being set up at runtime being the binding of DOM elements to those known-at-compile-time native handlers. The QML/XAML/NIB approach.
In your CSS to define
div.my { behavior:my-widget; }
While loading HTML that contains <div class="my"> you will get SC_ATTACH_BEHAVIOR callback with the DOM event handler reference. By handling SC_ATTACH_BEHAVIOR you will return DOM event handler (a.k.a. behavior) - just a native function pointer that receives all DOM events on that element: mouse, keyboard, etc.That's the same mechanism as HWND and WndProc but with lightweight DOM elements instead of Windows.
Example of such behavior that implements panels with tabs container: https://github.com/c-smile/sciter-sdk/blob/master/include/be...
https://sciter.com/sciter-fps/
Real FPS is shown in window's caption (490 FPS).
Sciter Engine (HTML/CSS/script) is fully contained in sciter.dll (4.9 Mb) (https://github.com/c-smile/sciter-sdk/tree/master/bin/32) without external dependencies. It works on all Windows versions starting from Windows XP and provides choice of four backends to use: Direct2D (GPU and WARP), Skia (OpenGL and CPU) and GDI+ (just in case someone is still interested in mammoth's shit).
On MacOS it uses Skia/OpenGL or CoreGraphics. On Linux it uses by default Cairo (good enough) and Skia/OpenGL as an option.
But in any case I am building sciter.dll as with Skia (sdk/bin/skia32/) as without it (sdk/bin/32/)
But surely it's non-optimal for native applications that have direct access to the native renderer and GUI systems, or at least to limit them to HTML and CSS and not some more optimal domain specific subset of XML?
[0]assuming one accepts the premise that "web apps" should even be a thing, which I know is controversial on HN to say the least...
Everyone knows how to produce "fuck it, it works" results with it.
Everything (almost) supports it.
It already runs on the web.
There's room in there for Ultralight, Awesomium, Chromium, Dear Imgui, SDL, Cairo, WPF, even GDI+.
That's basically because (I think) there's still a lot of effort being put into recreating UIs - especially for apps, games, and embedded.
(In embedded, as in, embedded systems running linux or VxWorks or something, the story is less well known, but it's the exact same balance and set of choices.)
In my app there will be lot of trees and mind-map style diagrams with traced signals. These will react to user input and as there is a change in state.
There is a need to support huge monitors or a multi screen setup so, I have currently ruled out Electron and looking at building a native tool as cross platform is not a priority.
Any suggestions are welcome.
I recently came across this excellent article comparing GUI frameworks [1]. It is definitely worth a read for anyone looking at building a serious desktop app. I have put my particular requirement in a longer format here if anyone is curious and has some suggestions [2]. [1]: http://blog.johnnovak.net/2016/05/29/cross-platform-gui-trai.... [2]: https://pastebin.com/8SUpcgWJ
It's not clear how much of a browser they are reimplementing. Features include XSLT and local storage, scroll bars, "text selection and dragging"? While on the to-do list is "full GIF support" and "CSS shadows." It's such a mixture of things that doesn't sound based on what you'd minimally need for a game UI.
"We've stripped WebKit to the bare essentials" - Sounds like maybe they took the non-rendering part of WebKit (eg layout) and wrote their own renderer(s)?
Fascinating.
- https://ultralig.ht/screen1.png
- https://ultralig.ht/screen2.png
- https://ultralig.ht/screen3.png
And yes, the renderer is completely new, this project has been in development for 4+ years.
But two things make it extremely valuable:
1. Ability to render css and js, so that web devs can build our app
2. Easily cross platform. This is so valuable to us.
Electron isn't just Chrome in a box. It's a whole ecosystem of libraries that dramatically accelerate and simplify cross-platform desktop development.
Just because you can get another project running on all platforms, that doesn't mean the experience is going to be a smooth one. There are so many potential boondoggles lurking here. Do you really want to bet your company on something that uses less RAM or CPU but could easily confront you with problems like, hmmm, suddenly 43% of your Windows users can no longer update their apps and you have no clue why and the maintainers aren't responding on Github?
Electron has its faults, but if we want to build something better, we should also understand its strengths. Despite its performance drawbacks, it's an impressive technology that gets many important things right.
It's still very early stages, but maybe interesting to you?
It has everything you mentioned, except HTML/CSS, but I'd argue QML is better than HTML/CSS for desktop.
20 years ago Windows had .dlg resources that define layout and content of dialog windows. .dlg is just a binary representation of serialized window DOM.
16 years ago Visual Basic had .frm files that are close to what now known as QML.
Et cetera.
So there is nothing new with markup defining UI structure. What is new and quite valuable is CSS with its declarativeness and cascading.
One gets to write a bit of CSS soup and then ensuring it works as expected across all target browsers.
It strips down a subset of HTML that can then be used to render UI across different base platforms. I feel like it could be a good starting point as well
I believe it's currently used by Youtube to render its HTML5 app on many set-top box devices
The other advantages are not really important. If an open source offering is lacking something, I can just add it myself. If the proprietary version is lacking something, I cannot.
You would be surprised. I can't even count on one hand the number of times I've send a patch upstream within the first 2 hours of using a new dependency.
I don't really care how long he spent on it. It was a waste of 4 years if it's just going to be proprietary.
Dogmatism all over again.
Don't bother with this hateful guy, you rock!
> you are blind to the many potential other benefits a project may have
What makes you think we aren't paying attention?
> This is proprietary, so it's a non-starter.
did not go into _any_ of the other details or aspects of the project.
Electron on the other hand is a full browser runtime, for better or worse. It probably would make more sense to create a cross-platform application packager which embeds the operating system's web-renderer into a window. But I think one of the main selling points of Electron is that you're guaranteed a specific version of the browser runtime, so your app suddenly won't stop working with a browser update.
Ultralight can render full websites just fine and is also a full browser runtime, the SDK ships with a Browser sample on macOS and Windows.
With that said, Ultralight is indeed somewhere between libRocket and Electron in terms of size and support. We won't support things that are unrelated to HTML UI (for example WebGL) and are able to reduce our dependencies/size/complexity by limiting said support.
That's what subset means.
Electron is MIT. Ultralight is proprietary. Electron always free to use even on comercial, ultralight only for small projects.
- It doesn't come with a DOM implementation, so most existing js libraries won't work. EDIT: actually it does have a DOM implementation, which is awesome
- Its API is in C++
- People are lazy
Ultralight addresses all of those through a new, lightweight WebKit fork geared specifically for embedding in other apps. This is a major rewrite and has taken 4+ years to complete. I am the former creator of Awesomium and decided to tackle this issue myself.
Also, the library does come with a DOM implementation and most existing JS libraries work just fine.
For reference, CEF is not much more lightweight than Electron. It still inherits Chrome's bloat and multiprocess weight. Also, webview only supports IE on Windows which is missing a lot of features.
- D3D 11 and metal required. Most likely huge compatibility/stability/rendering issues across different graphic cards and driver versions.
- Barrier to entry is one of the most important factors in a framework/library's success. You can't beat the Electron ecosystem where any idiot can make a cross platform app. This is really only useful for C++ developers.
As an idiot, I can attest to this. I'm constantly looking for lighter weight alternatives, but nothing so far has been nearly as simple as Electron. Here's the list of options I maintain: https://docs.google.com/spreadsheets/d/1dTZIp6z2J1IL7YgBlHG_...
- The Ultralight library itself has no dependencies on D3D11 or Metal. The renderer emits virtual GPU driver commands that are consumed by the user (see GPUDriver.h). We ship a few stock implementations of GPUDriver for major platforms but users can undoubtedly write their own.
Compare this to something like Qt, which is open source. But (as I understand it) it's LGPL licensed, meaning it can't be used commercially without paying the developer for a commercial license or releasing all the source code.
Of course, take this advice with a grain of salt. I've not really worked with Qt or Ultralight before, but I've been exploring my options for a project for a school club.
[1]: https://discuss.ultralig.ht/d/6-ultralight-0-9-beta-now-avai...
Edit: added source
That's nice, but not being open source means it will never have the breadth of players who both use it and contribute back that Electron does, which is why it won't beat Electron on the long term, even if it had some intriguing advantages.
That means you can dynamically link QT, and your program doesn't have to be (L)GPL. No commercial license required.
Edit: When I say open source, I didn't mean it has to be free of charge.
That's the largest text in the landing page and it's really confusing.
https://github.com/paulrouget/servo-embedding-example https://github.com/paulrouget/servoshell https://github.com/antoyo/servo-gtk
I wanted to know how that stacked up against some of my favorite and most used apps on windows, so I made a list: https://pastebin.com/KnkFcJXh (sorry, it's a bit long for HN).
I'll be honest, if I could publish a native app that's blazing fast, is cross platform, and whose size sits between Paint.NET (40) and VLC (130), and is even a fraction as useful as those two I would be downright ecstatic. I know for some people the final build size is a very important metric for native apps, and to those people I'm sorry. But if it's under 100MB and it uses about the same amount of ram I'm actually pretty ok with it, and I think a lot of others would agree with me.
Nope. JS engine is deeply integrated in Servo. Thus it can not be much better than Electron.
I looked into using this for a project and discovered this unfortunate result.
Which subset?
Regardless, I'm only interested if it is Open-Sourced.
To satisfy the licensing requirements of the LGPL license we have published our source code modifications [here] and made sure all WebCore code stays linked in a separate shared module."
With that said, the SDKs include full samples and framework code and all the API headers are documented so you can get up to speed fast.
- [1] https://ultralig.ht/docs
When the documentation is so sparse it begins to feel a little like vaporware.
http://docs.godotengine.org/en/3.0/getting_started/workflow/...
So, while people are in here talking about Electron, which is most likely not your target audience and might be confused as a result, I am your target audience. I am looking for ways to move away from my engine's imperative UI system and to migrate to web-based UIs in an OpenGL setting, and I have been for years.
Adam, this looks great, and I've been waiting to see new solutions like this in the game development space for quite some time now. However, the only truly viable solution at the moment in my opinion is still CEF. The proprietary aspect is significant, and while some using Unity and Unreal might be interested based on existing license restrictions, for these reasons, I am not.
Can you explain how Ultralight is fundamentally different than projects like Awesomium and libRocket? It seems very similar to your previous work and not enough of a differentiator for someone like myself. Could you tell me why I wouldn't use EAWebKit instead of this?
I spent years as a Source Engine developer and avoided both projects because of their proprietary nature, and because of lack of updates to their underlying web browser libraries.
I fear this is a repeat of Awesomium, with a similar proprietary nature, and operating in a space where we will not see frequent updates to the underlying web libraries, regardless of using a subset of web technologies that UI developers would care about.
Trust me, no one is more familiar with the issues of Awesomium (cumbersome licensing, slow update schedule, bloat, etc.) than myself and it was this reason that I decided to start over from the beginning.
Awesomium was similar in scope to CEF (and actually predates it by many months), it's goal was to wrap Chromium and make it accessible via a pixel buffer instead of a platform window.
Chromium in its initial stages was very tight and focused in its scope and only supported a subset of the current web platform we see today, I think the first Awesomium DLLs were something like 18MB or less.
Over the years Chromium grew larger and accumulated more complexity to a point where it was no longer a web renderer but something closer to an OS platform. Many of the features added were somewhat irrelevant for users looking to render HTML as a frontend but downstream developers like Awesomium and CEF had no choice but to integrate their updates as a whole since we were de-facto wrappers.
Ultralight is different. It's a hard fork of WebKit and has a considerable number of differences tuned specifically for embedders (such as the Platform API and virtual GPUDriver). We have much more control over the project and will continue making design decisions that benefit embedding as a first-class use-case.
Reasons to use Ultralight over EAWebKit are ease of use, pure GPU rendering and performance (EAWebKit, last I checked, depends on Cairo for all its rendering), and the backing of an actual commercial company that will support and maintain the product for years to come.
I appreciate the informative breakdown. It gives me a much better understanding of the value proposition. You have a particularly unique understanding of the challenges embedders have and it's great that we have another option in the industry. Thanks for your time!
Gonna be an interesting year for us Lua frameworks with this thing around. One of the principle 'reasons' for not using Lua for everything, is poor HTML support - welp, "lua_remove(that) -- and all the things..."
My personal favourite environment to solve the 'one codebase for all platforms' problem, has been .. MOAI. The reason is, it gives you everything you need from the browser/server relationship, with none of the bullshit; i.e. you use Lua for everything, and do nothing in HTML/CSS/javascript, etc.
Well, its been a nice ride. For my projects, MOAI has been very useful.
But with Ultralig.ht, the question is .. which part gets embedded in what. Naturally, it'll be a sinch to stitch UL->MOAI .. and with a nice result: can finally do business apps. ;)