{"id":13395190,"url":"https://github.com/fschutt/azul","last_synced_at":"2025-05-14T11:08:24.559Z","repository":{"id":37092138,"uuid":"117740918","full_name":"fschutt/azul","owner":"fschutt","description":"Desktop GUI Framework","archived":false,"fork":false,"pushed_at":"2025-04-09T10:56:42.000Z","size":28001,"stargazers_count":5996,"open_issues_count":51,"forks_count":223,"subscribers_count":110,"default_branch":"master","last_synced_at":"2025-05-07T10:52:37.615Z","etag":null,"topics":["c","cpp","desktop","desktop-gui-framework","gui","gui-framework","gui-library","opengl","rust"],"latest_commit_sha":null,"homepage":"https://azul.rs/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fschutt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"fschutt","ko_fi":"fschutt","liberapay":"fschutt","custom":["https://paypal.me/fschutt554","https://wise.com/pay/me/felixs1176"]}},"created_at":"2018-01-16T20:57:07.000Z","updated_at":"2025-05-07T05:17:48.000Z","dependencies_parsed_at":"2023-07-14T09:02:57.297Z","dependency_job_id":"9db09b1b-4f61-4cfd-8580-c1251047e05c","html_url":"https://github.com/fschutt/azul","commit_stats":{"total_commits":2261,"total_committers":36,"mean_commits":62.80555555555556,"dds":0.09862892525431222,"last_synced_commit":"423260da7c41e255b3bb917a1f86405161840f0e"},"previous_names":["maps4print/azul"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fschutt%2Fazul","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fschutt%2Fazul/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fschutt%2Fazul/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fschutt%2Fazul/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fschutt","download_url":"https://codeload.github.com/fschutt/azul/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254129481,"owners_count":22019628,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","cpp","desktop","desktop-gui-framework","gui","gui-framework","gui-library","opengl","rust"],"created_at":"2024-07-30T17:01:45.636Z","updated_at":"2025-05-14T11:08:19.549Z","avatar_url":"https://github.com/fschutt.png","language":"Rust","readme":"# Azul - Desktop GUI framework\r\n\r\n\u003c!-- [START badges] --\u003e\r\n[![CI](https://github.com/fschutt/azul/actions/workflows/rust.yml/badge.svg)](https://github.com/fschutt/azul/actions/workflows/rust.yml)\r\n[![Coverage Status](https://coveralls.io/repos/github/fschutt/azul/badge.svg?branch=master)](https://coveralls.io/github/fschutt/azul?branch=master)\r\n[![LICENSE](https://img.shields.io/badge/license-MPL--2.0-blue.svg)](LICENSE)\r\n[![Rust Compiler Version](https://img.shields.io/badge/rustc-1.58%20stable-blue.svg)]()\r\n[![dependency status](https://deps.rs/repo/github/fschutt/azul/status.svg)](https://deps.rs/repo/github/fschutt/azul)\r\n\u003c!-- [END badges] --\u003e\r\n\r\n\u003e Azul is a free, functional, reactive GUI framework for Rust, C and C++,\r\nbuilt using the WebRender rendering engine and a CSS / HTML-like document\r\nobject model for rapid development of beautiful, native desktop applications\r\n\r\n###### [Website](https://azul.rs/) | [Releases](https://azul.rs/releases) | [User guide](https://azul.rs/guide) | [API documentation](https://azul.rs/api) | [Video demo](https://www.youtube.com/watch?v=kWL0ehf4wwI) | [Matrix Chat](https://discord.gg/nxUmsCG)\r\n\r\n## Features\r\n\r\nAzul uses [webrender](https://github.com/servo/webrender) (the rendering engine behind \r\nFirefox) to render your UI, so it supports lots of common CSS features like:\r\n\r\n- gradients (linear, radial, conic)\r\n- box shadows\r\n- SVG filters\r\n- composition operators (multiply, darken, etc.)\r\n- border styling\r\n- border-radii\r\n- scrolling / automatic overflow\r\n- CSS transforms\r\n\r\nSee the [list of supported CSS keys / values](https://azul.rs/guide/1.0.0-alpha1/CSSstyling) for more info.\r\n\r\nOn top of that, Azul features...\r\n\r\n- lots of built-in widgets ([Button](https://azul.rs/api/1.0.0-alpha1#st.Button), [TextInput](https://azul.rs/api/1.0.0-alpha1#st.TextInput), [CheckBox](https://azul.rs/api/1.0.0-alpha1#st.CheckBox), [ColorInput](https://azul.rs/api/1.0.0-alpha1#st.ColorInput), [TextInput](https://azul.rs/api/1.0.0-alpha1#st.TextInput), [NumberInput](https://azul.rs/api/1.0.0-alpha1#st.NumberInput))\r\n- embedding OpenGL textures\r\n- simplified HTML-like relative/absolute layout system based on CSS flexbox\r\n- 60+ FPS animations via [Animation](https://azul.rs/api/1.0.0-alpha1#st.Animation) API\r\n- cross-platform native dialogs\r\n- cross-platform text shaping and rendering\r\n- SVG parsing and rendering\r\n- shape tesselation for rendering large numbers of 2D lines, circles, rects, shapes, etc. in a single draw call\r\n- managing off-main-thread tasks for I/O\r\n- dynamic linking via shared library\\*\r\n- usable from Rust, C, C++ and Python via auto-generated API bindings\\**\r\n- HTML-to-Rust compilation for fast prototyping / hot reload\r\n\r\n\\* static linking not yet available\r\n\r\n\\** C++ bindings and Python are not yet stabilized and might not work depending\r\non the branch you're using. They will be stabilized before the release.\r\n\r\n## Screenshots \r\n\r\n![image](https://user-images.githubusercontent.com/12084016/129535820-ca2b56a6-fdb5-4d0d-b043-a7f5394339e9.png)\r\n![image](https://user-images.githubusercontent.com/12084016/129535780-69b9365b-ad87-439f-9d10-d416991de8fc.png)\r\n![image](https://user-images.githubusercontent.com/12084016/128639991-e98c0b92-66df-4ad8-973b-c9d45c68d5b3.png)\r\n![image](https://user-images.githubusercontent.com/12084016/126752996-1ec1f221-2b01-4f01-99c6-794640228d59.png)\r\n\r\n## Hello World\r\n\r\n### Python\r\n\r\n```py\r\nfrom azul import *\r\n\r\nclass DataModel:\r\n    def __init__(self, counter):\r\n        self.counter = counter\r\n\r\ndef render_dom(data, info):\r\n    \r\n    label = Dom.text(\"{}\".format(data.counter))\r\n    label.set_inline_style(\"font-size: 50px;\")\r\n    \r\n    button = Button(\"Increment counter\")\r\n    button.set_on_click(data, increment_counter)\r\n\r\n    dom = Dom.body()\r\n    dom.add_child(label)\r\n    dom.add_child(button.dom())\r\n\r\n    return dom.style(Css.empty())\r\n\r\ndef increment_counter(data, info):\r\n    data.counter += 1;\r\n    return Update.RefreshDom\r\n\r\napp = App(DataModel(5), AppConfig(LayoutSolver.Default))\r\napp.run(WindowCreateOptions(render_dom))\r\n```\r\n\r\n### Rust\r\n\r\n```rust\r\nuse azul::prelude::*;\r\nuse azul::widgets::{button::Button, label::Label};\r\n\r\nstruct DataModel {\r\n    counter: usize,\r\n}\r\n\r\nextern \"C\" \r\nfn render_dom(data: \u0026mut RefAny, _: \u0026mut LayoutInfo) -\u003e StyledDom {\r\n\r\n    let data = data.downcast_ref::\u003cDataModel\u003e()?;\r\n\r\n    let label = Dom::text(format!(\"{}\", data.counter))\r\n        .with_inline_style(\"font-size: 50px;\");\r\n        \r\n    let button = Button::new(\"Increment counter\")\r\n        .onmouseup(increment_counter, data.clone());\r\n\r\n    Dom::body()\r\n    .with_child(label)\r\n    .with_child(button.dom())\r\n    .style(Css::empty())\r\n}\r\n\r\nextern \"C\" \r\nfn increment_counter(data: \u0026mut RefAny, _: \u0026mut CallbackInfo) -\u003e Update {\r\n    let mut data = data.downcast_mut::\u003cDataModel\u003e()?;\r\n    data.counter += 1;\r\n    Update::RefreshDom // call render_dom() again\r\n}\r\n\r\nfn main() {\r\n    let initial_data = RefAny::new(DataModel { counter: 0 });\r\n    let app = App::new(initial_data, AppConfig::default());\r\n    app.run(WindowCreateOptions::new(render_dom));\r\n}\r\n```\r\n\r\n### C\r\n\r\n```c\r\n#include \"azul.h\"\r\n\r\ntypedef struct {\r\n    uint32_t counter;\r\n} DataModel;\r\n\r\nvoid DataModel_delete(DataModel* restrict A) { }\r\nAZ_REFLECT(DataModel, DataModel_delete);\r\n\r\nAzStyledDom render_dom(AzRefAny* data, AzLayoutInfo* info) {\r\n\r\n    DataModelRef d = DataModelRef_create(data);\r\n    if !(DataModel_downcastRef(data, \u0026d)) {\r\n        return AzStyledDom_empty();\r\n    }\r\n    \r\n    char buffer [20];\r\n    int written = snprintf(buffer, 20, \"%d\", d-\u003ecounter);\r\n    AzString const labelstring = AzString_copyFromBytes(\u0026buffer, 0, written);\r\n    AzDom label = AzDom_text(labelstring);\r\n    AzString const inline_css = AzString_fromConstStr(\"font-size: 50px;\");\r\n    AzDom_setInlineStyle(\u0026label, inline_css);\r\n    \r\n    AzString const buttontext = AzString_fromConstStr(\"Increment counter\");\r\n    AzButton button = AzButton_new(buttontext, AzRefAny_clone(data));\r\n    AzButton_setOnClick(\u0026button, incrementCounter);\r\n\r\n    AzDom body = Dom_body();\r\n    AzDom_addChild(body, AzButton_dom(\u0026button));\r\n    AzDom_addChild(body, label);\r\n    \r\n    AzCss global_css = AzCss_empty();\r\n    return AzDom_style(body, global_css);\r\n}\r\n\r\nUpdate incrementCounter(RefAny* data, CallbackInfo* event) {\r\n    DataModelRefMut d = DataModelRefMut_create(data);\r\n    if !(DataModel_downcastRefMut(data, \u0026d)) {\r\n        return Update_DoNothing;\r\n    }\r\n    d-\u003eptr.counter += 1;\r\n    DataModelRefMut_delete(\u0026d);\r\n    return Update_RefreshDom;\r\n}\r\n\r\nint main() {\r\n    DataModel model = { .counter = 5 };\r\n    AzApp app = AzApp_new(DataModel_upcast(model), AzAppConfig_default());\r\n    AzApp_run(app, AzWindowCreateOptions_new(render_dom));\r\n    return 0;\r\n}\r\n```\r\n\r\n## License\r\n\r\nAzul is licensed under the MPL-2.0. Which means that yes, you can build \r\nproprietary applications using azul without having to publish your code: \r\nyou only have to publish changes made to *the library itself*.\r\n\r\nCopyright 2017 - current Felix Schütt\r\n","funding_links":["https://github.com/sponsors/fschutt","https://ko-fi.com/fschutt","https://liberapay.com/fschutt","https://paypal.me/fschutt554","https://wise.com/pay/me/felixs1176"],"categories":["Rust","Libraries","库 Libraries","HTML"],"sub_categories":["GUI","GUI GUI","Rust"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffschutt%2Fazul","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffschutt%2Fazul","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffschutt%2Fazul/lists"}