Qt for WebAssembly

You may have seen the news that Qt Project released Qt for WebAssembly tech preview. (You can now Try Qt for WebAssembly for Free today. Try the latest Qt here.)

We use Emscripten to compile Qt into something that runs in a web browser from a web server. Instead of compiling and deploying for multiple platforms, the idea is to compile and deploy on a web server for any platform that has a browser that supports WebAssembly. If you are an enterprise and have multiple clients that have various platforms in use, you could use Qt for WebAssembly to compile your Qt or Quick app and deploy once.

Qt for WebAssembly build instructions are listed on Qt for WebAssembly wikiYou will first need to download and setup the emsdk compiler. It’s fairly trivial to do. We use this as the cross-compiler.


Debugging is a bit arcane as there is no gdb, but there are output statements (std::cout, qDebug and printf) as well as the debugger console in the browser. You might also have to increase the Web console log limit with (Firefox) "devtools.hud.loglimit.console" from about:config.

To set a breakpoint, add

EM_ASM({ debugger });  

into your code to popup the browser debugger. (Don't forget to #include <emscripten.h>) The downside is that you need to recompile.


Not everything works perfectly, but here are some screenshots of a few working examples:



Standarddialogs: showing multiple windows


QOpenGLWindow works and seems to get near 60 fps. Although they are 'full screen' windows currently, which means they will take up the full browser window. QOpenGLWidget still has some issues. Some shaders seem to have some issues.

Emscripten translates OpenGL calls in WegGL, so there are limitations from the desktop and embedded versions.



Besides QtBase and QtDeclarative that use the ‘wip/webassembly’ branch, Qt modules known to work are:

  • QtCharts
  • QtGraphicalEffects
  • QtQuickControls
  • QtQuickControls2
  • QtWebSockets
  • QtMqtt (using WebSocketIODevice from the websockets example)

To use QtMqtt, you will need to integrate the WebSocketIODevice class from the websocketsubscription example in QtMqtt into your app.

There is also a WIP MR for a backend to QtSensors for orientation changes on mobiles (including laptops) that I have thrown together which compiles, but hasn’t been tested.

Qml clocks:


Since javascript and webassembly have only one thread, QtDeclarative was made to work with only one thread.




QtCharts, QtGraphicalEffects, QtQuickcontrols, QtQuickControls2 all work without changes.

QtCharts oscilloscope:


IoT sensor demo showing demo data


There is a WIP merge request for clipboard support, but it is unfinished at this time. It is working for simple text.

Things that don't work QTBUG-63917

  • Multithreading QTBUG-64700
    • there is a stub QThread
    • disabled in the browsers due to the Spectre vulnerability
  • Most QNetwork QTBUG-63920
    • no DNS lookups due to javascript sandbox
    • simple QNAM requests should work.
  • Local Filesystem access QTBUG-67834
  • persistent QSettings, it syncs the config rather slow and asynchronously QTBUG-63923
  • QOpenGLWIdget QTBUG-66944
  • Opengl only works fullscreen QTBUG-67717
  • some shaders QTBUG-67338
    • QResource fails to find shaders built-in to Qt
  • The exec loop does not function like other platforms QTBUG-64020
    • exec() event loop will not return where you expect it to
    • Returning values from modal dialogs are known not to work but can be worked around by using non-modal signals and show(). Although modal dialogs/windows will still open.
  • toUpperCase QTBUG-66621
  • QClipboard QTBUG-64638



Blog Topics: