fschutt/azul
Desktop GUI Framework
Healthy across all four use cases
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 2w ago
- ✓MIT licensed
- ✓CI configured
Show all 5 evidence items →Show less
- ✓Tests present
- ⚠Solo or near-solo (1 contributor active in recent commits)
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/fschutt/azul)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/fschutt/azul on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: fschutt/azul
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/fschutt/azul shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across all four use cases
- Last commit 2w ago
- MIT licensed
- CI configured
- Tests present
- ⚠ Solo or near-solo (1 contributor active in recent commits)
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live fschutt/azul
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/fschutt/azul.
What it runs against: a local clone of fschutt/azul — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in fschutt/azul | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 42 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of fschutt/azul. If you don't
# have one yet, run these first:
#
# git clone https://github.com/fschutt/azul.git
# cd azul
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of fschutt/azul and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "fschutt/azul(\\.git)?\\b" \\
&& ok "origin remote is fschutt/azul" \\
|| miss "origin remote is not fschutt/azul (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "core/src/lib.rs" \\
&& ok "core/src/lib.rs" \\
|| miss "missing critical file: core/src/lib.rs"
test -f "core/src/dom.rs" \\
&& ok "core/src/dom.rs" \\
|| miss "missing critical file: core/src/dom.rs"
test -f "core/src/styled_dom.rs" \\
&& ok "core/src/styled_dom.rs" \\
|| miss "missing critical file: core/src/styled_dom.rs"
test -f "css/src/lib.rs" \\
&& ok "css/src/lib.rs" \\
|| miss "missing critical file: css/src/lib.rs"
test -f "core/src/ui_solver.rs" \\
&& ok "core/src/ui_solver.rs" \\
|| miss "missing critical file: core/src/ui_solver.rs"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 42 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~12d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/fschutt/azul"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Azul is a functional, reactive desktop GUI framework for Rust that uses the WebRender rendering engine to build native applications with a CSS/HTML-like DOM model. It compiles to native binaries for macOS, Linux, and Windows, allowing developers to write UIs declaratively in Rust without JavaScript or web runtimes. Workspace monorepo with 5 primary crates: core/src/ contains the DOM, styling, layout engine (ui_solver.rs), hit testing, and event system; css/ is the CSS parser; layout/ depends on core+css; dll/ wraps everything for C FFI; examples/rust/ has sample applications. GPU rendering happens through gl.rs/gpu.rs interfacing with WebRender.
👥Who it's for
Rust developers building cross-platform desktop applications who want CSS-based styling, reactive data binding, and native performance without learning Qt/GTK or running Electron. Particularly suited for developers familiar with React-style functional UI patterns but wanting type safety and no JavaScript overhead.
🌱Maturity & risk
Experimental and under heavy active development—the README explicitly warns 'NOT usable yet' and the last stable release was 2+ years old. The codebase is substantial (15.6MB Rust code) with comprehensive test files (cascade.rs, diff.rs, dom_manipulation.rs) and CI via GitHub Actions, but APIs change frequently and core features remain incomplete.
High risk: single primary maintainer (fschutt), declared incomplete/unstable status in README, and 2+ year gap since last release suggest slow progress. No visible breaking-change policy or semantic versioning discipline documented. The monorepo spans 5+ interdependent crates (core, css, layout, dll, examples) creating tight coupling.
Active areas of work
Active refactoring of rendering and layout subsystems—the WARNING in README points to https://azul.rs/reftest as the current development focus for the HTML/CSS layout engine. The repo shows work on DOM diffing (diff.rs), CSS cascade/inheritance (tests/cascade.rs, tests/css_inheritance.rs), and accessibility support (a11y.rs), but no recent public commits visible in the summary.
🚀Get running
git clone https://github.com/fschutt/azul.git
cd azul
cd dll
cargo build --release
For cross-compilation to Linux/Windows from macOS, follow CROSS_COMPILATION.md and add targets via rustup target add x86_64-unknown-linux-gnu x86_64-pc-windows-gnu.
Daily commands:
cd examples/rust
cargo run --release
Or build the core library for testing: cd core && cargo test --release. For layout/CSS testing: cd layout && cargo test or cd css && cargo test.
🗺️Map of the codebase
core/src/lib.rs— Entry point for the core library; defines public API surface and module structure for the GUI frameworkcore/src/dom.rs— Defines the Document Object Model (DOM) abstraction; essential for understanding how UI structure is representedcore/src/styled_dom.rs— Applies CSS styling to DOM nodes; critical for the cascade, inheritance, and style resolution pipelinecss/src/lib.rs— CSS parser and property system; foundational dependency that core and layout depend oncore/src/ui_solver.rs— Layout solver that computes positions and dimensions; bridges CSS to renderingcore/src/callbacks.rs— Event callback and state management system; orchestrates user interactions with UIcore/src/gpu.rs— GPU rendering abstraction using WebRender; final stage of visual pipeline
🛠️How to make changes
Add a New CSS Property
- Define the property enum variant and default value in the appropriate module under css/src/props/ (
css/src/props/basic/mod.rs or css/src/props/layout/mod.rs (depending on property type)) - Implement parsing logic in css/src/parser2.rs to tokenize and parse the property value (
css/src/parser2.rs) - Add property handling in core/src/style.rs to resolve it in the cascade (
core/src/style.rs) - Update core/src/ui_solver.rs if the property affects layout (size, spacing, positioning) (
core/src/ui_solver.rs) - Add test cases in core/tests/ (e.g., cascade.rs, css_inheritance.rs) to verify cascade and inheritance behavior (
core/tests/cascade.rs)
Add a New Event Type
- Define the event struct and variant in core/src/events.rs (
core/src/events.rs) - Implement event routing logic in core/src/hit_test.rs to dispatch events to the correct DOM node (
core/src/hit_test.rs) - Add callback handlers in core/src/callbacks.rs to bind event listeners to DOM nodes (
core/src/callbacks.rs) - Wire platform events in core/src/window.rs to map OS events to your new event type (
core/src/window.rs) - Add tests in core/tests/events.rs to verify event dispatch and callback execution (
core/tests/events.rs)
Implement a Layout Algorithm Enhancement
- Understand the current layout solver entry point and constraint propagation (
core/src/ui_solver.rs) - Add geometric computation helpers if needed in core/src/geom.rs (
core/src/geom.rs) - Modify constraint handling or flex/grid logic in core/src/ui_solver.rs (
core/src/ui_solver.rs) - Add regression and correctness tests with known layouts (
core/tests/restyle_unified.rs)
Add a Custom Drawing/Rendering Feature
- Define a new drawing primitive or effect in core/src/gpu.rs or as a new module (
core/src/gpu.rs) - Implement shader code if needed (GLSL); reference core/src/gl_fxaa.rs as an example (
core/src/gl_fxaa.rs) - Add OpenGL state management in core/src/gl.rs (
core/src/gl.rs) - Integrate rendering dispatch in core/src/window.rs or the main render loop (
core/src/window.rs) - Test visually by creating a minimal example or updating existing examples (
examples/rust/ (add or modify example file))
🔧Why these technologies
- Rust — Memory safety without GC; performance critical for real-time rendering and low latency event handling
- WebRender — Battle-tested GPU rendering engine from Mozilla; handles text, vectors, and compositing efficiently at 60+ FPS
- CSS + HTML-like DOM — Familiar declarative API for web developers; leverages existing CSS knowledge for rapid UI development
- Flex/Grid Layout — Modern, constraint-based layout system; expressive and predictable compared to manual positioning
- OpenGL (via gl wrapper) — Direct GPU control for custom effects (e.g., FXAA); cross-platform via WebRender abstraction
⚖️Trade-offs already made
- Reactive (diff-based) updates instead of immediate-mode GUI
- Why: undefined
- Consequence: undefined
🪤Traps & gotchas
No documented MSRV (Minimum Supported Rust Version)—badge claims 1.88 stable but Cargo.toml may not enforce it; verify locally. WebRender vendoring: gpu.rs depends on WebRender which may require specific system graphics libraries (EGL, Metal, DirectX depending on platform). CSS parser state: css/ is a separate crate with its own version; mismatches can cause subtle styling bugs. UI solver non-standard: ui_solver.rs appears custom, not Taffy or Druid's flex impl—behavioral differences vs. browser CSS should be expected. No published crate on crates.io (dll points to local deps)—internal development only. Test coverage: tests exist but coverage is incomplete (e.g., no visible tests for svg.rs, menu.rs, selection.rs).
🏗️Architecture
💡Concepts to learn
- DOM Diffing and Reconciliation — core/src/diff.rs implements the algorithm to detect minimal changes between old and new DOM trees, reducing unnecessary reflows—fundamental to Azul's reactive efficiency
- CSS Cascade and Specificity — styled_dom.rs and tests/cascade.rs implement CSS specificity rules and cascade order; essential for understanding why styles are applied and how to debug styling issues
- Hit Testing and Event Routing — hit_test.rs and events.rs implement spatial indexing to route input events to the correct DOM node; critical for interactive applications and touch/mouse handling
- Constraint-based Layout Solving — ui_solver.rs appears to use constraint satisfaction (similar to Cassowary algorithm) to resolve flex/grid layouts; understanding this is key to debugging layout bugs
- GPU Batch Rendering and Display Lists — gpu.rs compiles DOM into WebRender display lists for GPU execution; knowledge of WebRender's command buffer and batching is needed for rendering optimization
- Functional Reactive Programming (FRP) — Azul's architecture treats UI as a pure function of state (styled_dom.rs applies styles to DOM); FRP patterns are central to the reactive update model
- FFI (Foreign Function Interface) and C ABI — dll/Cargo.toml wraps Rust code for C/C++ consumers; understanding Rust's #[repr(C)] and memory safety across language boundaries is needed for bindings work
🔗Related repos
DioxusLabs/dioxus— React-style declarative Rust GUI framework; modern alternative to Azul with similar goals but active development and stable releaseslinebender/druid— Data-first Rust GUI toolkit using custom layout (similar to Azul's ui_solver approach); smaller but more stable, good reference for architectural patternsservo/webrender— The GPU rendering engine Azul wraps (core/src/gpu.rs); understanding its API is essential for Azul's render pathtaffy-rs/taffy— Modern async CSS layout library in Rust; Azul could migrate from custom ui_solver to this for better standards compliance
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive integration tests for CSS cascade and inheritance rules
The repo has core/tests/cascade.rs and core/tests/css_inheritance.rs, but these appear to be basic test files. Given that azul is a CSS-based GUI framework with a custom CSS parser (css/ module), there's an opportunity to significantly expand test coverage for edge cases in CSS specificity, cascade resolution, and property inheritance chains. This is critical because incorrect CSS handling directly impacts UI rendering across all applications.
- [ ] Review existing tests in core/tests/cascade.rs and core/tests/css_inheritance.rs to identify gaps
- [ ] Add tests for CSS specificity conflicts (inline vs class vs element selectors)
- [ ] Add tests for property inheritance with pseudo-elements and custom element states
- [ ] Add tests for cascade resolution with !important declarations and author/user/browser stylesheets
- [ ] Add tests for computed value resolution in core/src/style.rs
- [ ] Run with coverage profile to ensure new tests increase coverage metrics
Add GitHub Action workflow for platform-specific GUI rendering tests
The repo has core/tests/diff.rs and tests for styled DOM, but the CI workflow (.github/workflows/rust.yml) likely only runs basic Rust tests. Desktop GUI frameworks need platform-specific rendering validation. Adding a workflow that runs GUI snapshot/regression tests on Windows, macOS, and Linux would catch rendering regressions early. This is especially important for hit_test.rs, gpu.rs, and gl.rs which are platform-sensitive.
- [ ] Examine current .github/workflows/rust.yml to understand existing CI structure
- [ ] Create core/tests/gpu_rendering_tests.rs with snapshot comparison tests for core/src/gpu.rs output
- [ ] Add a new GitHub Action workflow that runs GUI tests on ubuntu-latest, windows-latest, and macos-latest
- [ ] Integrate snapshot testing library (e.g., insta) for comparing rendered outputs
- [ ] Add screenshot comparison logic that validates hit_test.rs and gl.rs rendering across platforms
Add missing unit tests for event system and drag-drop functionality
The repo has core/tests/events.rs but drag.rs (core/src/drag.rs) appears to lack dedicated test coverage based on the file structure. Drag-and-drop is a critical user interaction feature in GUI frameworks. Adding comprehensive tests for drag state transitions, hit testing during drags, and event ordering will improve reliability and prevent regressions when modifying the drag system.
- [ ] Create core/tests/drag_drop.rs with tests for drag initiation, movement, and drop events
- [ ] Add tests in core/tests/drag_drop.rs validating hit_test.rs integration with moving elements
- [ ] Add tests for drag state machine transitions (idle → dragging → dropped)
- [ ] Add tests for multi-touch drag scenarios and pointer event conflicts
- [ ] Verify event ordering tests in core/tests/events.rs include drag event sequences
- [ ] Add property-based tests using proptest to validate drag state transitions
🌿Good first issues
- Add comprehensive tests for svg.rs module: core/src/svg.rs has no visible test file in core/tests/; SVG rendering is unvalidated. Start by writing tests/svg.rs mirroring the structure of tests/cascade.rs to ensure basic SVG parsing and rendering.
- Document CSS cascade behavior and inheritance rules: core/src/style.rs and styled_dom.rs implement cascade logic but lack inline docs. Add doc comments explaining specificity calculation and property inheritance (especially for custom properties); reference tests/css_inheritance.rs for ground truth.
- Add hit_test integration tests with real DOM examples: core/src/hit_test.rs and hit_test_tag.rs implement event hit testing but have no visible tests in core/tests/. Write integration tests that verify hit detection on nested, transformed, and clipped DOM nodes (test against dom_manipulation.rs patterns).
📝Recent commits
Click to expand
Recent commits
e57d9e9— Update GlShader::draw to use gl::PRIMITIVE_RESTART (fschutt)2dc2b8b— Update PERF2 plan (fschutt)a77487f— Fix scrollbar fade causing infinite repaint loop (fschutt)ee04bb0— Fix R8 image mask rendering: keep native format and enable mask render path (fschutt)4bc8926— Replace WebRender hit-tester with CPU-side scrollbar geometry for hit testing (fschutt)f270a98— Update contenteditable.c: return DoNothing from on_key_down, fix API changes (fschutt)8c7e62e— Fix debug server: prevent DOM rebuild on key/text events, add Backspace/Delete (fschutt)ea18af5— Fix macOS handle_text_input to use ShouldUpdateDisplayListCurrentWindow (fschutt)5a6d59e— Fix text relayout: resolve CSS font properties and use dom_to_layout for IFC lookup (fschutt)a39515e— Add display_list_dirty flag to separate text edit repaints from full DOM rebuilds (fschutt)
🔒Security observations
The Azul desktop GUI framework codebase shows generally good security posture with no critical vulnerabilities detected in the static analysis. The main concerns are build profile configurations (LTO disabled, debug symbols retained, panic abort strategy) that are documented as temporary measures for profiling purposes. These should be revisited for production releases. The project properly uses workspace-based dependency management and maintains a clean file structure. No hardcoded secrets, injection vulnerabilities, or exposed configurations were identified in the visible structure. The primary recommendations are to finalize production build profiles and establish a documented security reporting policy.
- Medium · LTO Disabled in Release Profile —
Cargo.toml - [profile.release]. Link Time Optimization (LTO) is disabled in the release profile (lto = false). While documented as a temporary measure for profiling, LTO disables certain compiler optimizations that can help prevent certain classes of vulnerabilities and reduces code size. Fix: Re-enable LTO (lto = true or 'fat') for production releases after profiling is complete to benefit from additional compiler-level optimizations and security hardening. - Medium · Panic Abort Strategy in Release Profile —
Cargo.toml - [profile.release]. The release profile uses 'panic = abort' which removes stack unwinding code. While this reduces binary size, it prevents graceful error handling and recovery in some scenarios. This could lead to abrupt termination without cleanup. Fix: Consider using 'panic = unwind' to allow for proper resource cleanup and error recovery in production. If size is critical, use selective unwinding or ensure abort handlers are properly implemented. - Low · Debug Symbols Retained in Release Build —
Cargo.toml - [profile.release]. Debug symbols are retained in the release profile (debug = 1). While useful for debugging, this increases binary size and could potentially expose implementation details. Fix: For production builds, consider setting debug = 0 or using split-debug-info to separate debug symbols into external files that can be managed separately from the binary distribution. - Low · Symbols Not Stripped in Release Profile —
Cargo.toml - [profile.release]. Symbols are not stripped from the release binary (strip = false). While useful for debugging and profiling, unstripped binaries are larger and may expose function names and implementation details. Fix: For production distributions, consider setting 'strip = true' to reduce binary size and minimize information disclosure, while maintaining separate symbol files for debugging if needed. - Low · No Observable Security Policy or Process —
Repository root. No SECURITY.md or security policy file is documented in the repository structure. This makes it unclear how security vulnerabilities should be reported responsibly. Fix: Add a SECURITY.md file documenting responsible disclosure procedures, including how to report vulnerabilities privately and the expected response timeline.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.