Built for beauty
and speed
Cross-platform Desktop GUI framework for C, C++, Python and Rust, using the Mozilla WebRender rendering engine, licensed MPL-2.0

- Memory: 23MB
- CPU: 0%
Objects are composed into a DOM hierarchy which only gets re-rendered when a callback returns RefreshDom
. The resulting DOM tree can be styled with CSS.
from azul import *
class DataModel:
def __init__(self, counter):
self.counter = counter
# model -> view
def my_layout_func(data, info):
label = Dom.text("{}".format(data.counter))
label.set_inline_style("font-size: 50px")
button = Button("Update counter")
button.set_on_click(data, my_on_click)
button = button.dom()
button.set_inline_style("flex-grow:1")
root = Dom.body()
root.add_child(label)
root.add_child(button)
return root.style(Css.empty())
# model <- view
def my_on_click(data, info):
data.counter += 1;
return Update.RefreshDom
model = DataModel(5)
app = App(model, AppConfig(LayoutSolver.Default))
app.run(WindowCreateOptions(my_layout_func))

- Memory: 23MB
- CPU: 0%
The UI structure is created via composition instead of inheritance. Callbacks can modify the application data and then tell the framework to reconstruct the entire UI again - but only if it's necessary, not on every frame.
from azul import *
class DataModel:
def __init__(self, counter):
self.counter = counter
# model -> view
def my_layout_func(data, info):
label = Dom.text("{}".format(data.counter))
label.set_inline_style("font-size: 50px")
button = Button("Update counter")
button.set_on_click(data, my_on_click)
button = button.dom()
button.set_inline_style("flex-grow:1")
root = Dom.body()
root.add_child(label)
root.add_child(button)
return root.style(Css.empty())
# model <- view
def my_on_click(data, info):
data.counter += 1;
return Update.RefreshDom
model = DataModel(5)
app = App(model, AppConfig(LayoutSolver.Default))
app.run(WindowCreateOptions(my_layout_func))

- Memory: 23MB
- CPU: 0%
Azul supports lazy loading and can render infinitely large datasets (such as a table, shown here) while using a comparably small amount of memory. DOM nodes share their CSS style efficiently via pointers, so that properties do not get duplicated in memory.
from azul import *
def main():
pass

- Memory: 23MB
- CPU: 0%
Azul contains a SVG1.1 compatible SVG renderer as well as functions for tesselating and drawing shapes to OpenGL textures. Images / textures can be composited as clip masks and even be animated.
from azul import *
def main():
pass

- Memory: 23MB
- CPU: 0%
Composing larger UIs is just a matter of proper function composition. Widget-specific data is either stored on the callback object itself - or on the DOM node, similar to a HTML 'dataset' attribute.
from azul import *
def main():
pass

- Memory: 23MB
- Memory: 0%
Azul contains an XML-based UI description which can be instantly hot-reloaded from a file. After prototyping the UI in XML / CSS, you can compile the code to a native language in order to get both fast design iteration times as well as performant code.
from azul import *
def main():
pass