Experimental Qt and QML in the browser
Update: You might also be interested in the discussion on Hacker News.
I was amazed when I read Morten Johan Sørvig’s blog post about bringing Qt to Native Client (NaCl) and Emscripten in September last year. I have been following multiple efforts to bring Qt to the web for some time. Mostly because I wanted to make my own Qt projects easily available to others, but also because I find the whole concept of running C++ code in a browser fascinating.
This is definitely not the first time someone has worked on bringing Qt to the browser. Qt4 was ported to Emscripten by Simon St James and published with a lot of examples. However, it seems the port was discontinued when Qt5 came along due to the changes that came with that transition. In the meantime, Lauri Paimen, Anton Kreuzkamp and many others have contributed to qmlweb, a QML interpreter written from scratch in JavaScript. That project does however not make it easy to use any C++ classes you may have defined. And most of my projects are QML/C++ hybrids.
These projects brought something important to the table and took us one step closer to writing QML for the browser. Personally I find QML very enjoyable because of its clean and intuitive structure in comparison to other options like XML. And the ability to easily bind GUI elements to high-performance C++ code has made Qt my favorite framework for many projects.
I tried to port Qt5 to Emscripten myself about a year ago. That turned out to be a real challenge. I based my work on the changes Simon St James made to Qt4 and tried to figure out how to make the same changes in Qt5. After a couple of weeks, I got to the point where I had QtCore running and QtDeclarative (QML) compiling, but other things caught up with me and I had to leave that project behind. The biggest disappointment was that I never got around to making any demos.
I decided to pick up the ball a couple of months ago This time I knew about Morten Johan Sørvig’s efforts and asked him to give me some info on the status of his port. At that point he had support for compiling to NaCl ready (that means Chrome only) and he had already started porting to Emscripten using pepper.js as glue between Emscripten and NaCl. There was still a bit left to do before any examples could be up and running in Firefox. I decided to give it a go and see if I could contribute with something.
A couple of weeks later, I managed to get Qt running in Firefox with a number of QML examples. The process was a lot of fun as I learned much about what happens inside Qt’s sources. It was interesting to see how often I could write many lines of code and rebuild multiple times only to arrive at a one-line change that fixed the issue at hand. I was really happy when I finally could send a patch to Qt’s NaCl branch. The main changes were to Qt’s event loop, which would hang if control wasn’t returned to the browser. I had to add a couple of hacks to keep Qt’s mutexes from locking up everything (this needs to be properly fixed later, perhaps by creating pthread stubs). And OpenGL needed to be explicitly set to OpenGL ES2 in addition to a bunch of smaller modifications.
[](http://ovilab.net/projects/qt-emscripten/qml-sandbox) QML sandbox running in Firefox. See the links below for a live demo.[/caption]
Below are two resulting demos of QML running in the browser. I’m amazed with the performance both in Firefox and Chrome. Just be aware that the size of the examples is quite big because no optimizations have been done to reduce the size of the binary JavaScript. Further, there may be lots of bugs and some browsers where the examples don’t work. Remember that this is still very experimental and only a small taste of what may be possible with Qt in the browser in the future:
What amazes me the most is the fact that we are now running Qt’s own JavaScript engine, which is written in C++ and compiled to JavaScript with Emscripten, inside the browser’s own JavaScript engine! I really want to see if we can get QML’s WebEngineView running inside itself inside Firefox. That’s a step on the way to true inception, which reminds me of a great talk by Gary Bernhardt titled “The Birth & Death of JavaScript”.