A modern GUI library for Ada.
Adi2 gives you a real widget toolkit with the niceties developers expect from a modern UI stack — CSS-like styling with live reload, declarative XML layouts, animations, SVG and Lottie graphics, internationalization, and asset bundling — implemented natively in Ada on top of SDL3.
Status: in production use, but not yet a stable release — APIs may still change between versions.
.css syntax. Edit the file, save, see the change. No recompile during development. Prefer pure Ada? CSS rules are just plain Ada aggregates of Style_Rules — write them by hand with no extra ceremony (see the snippet below).<button>, <grid>, <text-editor> in XML and let the toolchain emit clean Ada packages, or construct the same widget tree directly in Ada with handle-based builders. Both paths target the exact same API; the XML generator is a convenience, not a requirement..po → Ada compilation.color, background-color, border-color, border-width, border-radius, padding, margin, opacity, box-shadow and font-size — the framework handles interpolation and timing.dp/dip for layout, rem for typography, pix when you mean one renderer pixel exactly, and px — which follows the display scale or not, depending on Set_Px_Maps_To_Dip. See docs/css_styling.md.wasm/ for the build.A release build links statically into a single executable under 10 MB — the widget toolkit, the CSS engine, SVG and Lottie rendering, all of it. Whatever assets you bundle add their own weight to that.
It draws through SDL's renderer, which binds to whatever the host offers: Direct3D on Windows, Metal on macOS, Vulkan or OpenGL where they exist, software as the floor. Windows XP takes Direct3D 9 and a current Mac takes Metal, from the same source.
| Adi2 | Qt | Flutter | Electron | |
|---|---|---|---|---|
| Ship size | <10 MB, one file | ~15–30 MB static; otherwise a Qt runtime alongside | ~20 MB+, engine plus a data directory | ~100 MB+, bundling Chromium and Node |
| Runtime | self-contained | Qt libraries and plugins | Flutter engine; GTK3 on Linux | Chromium and Node |
| Graphics | SDL renderer, software fallback included | GPU or raster backends | Skia or Impeller, GPU expected | GPU stack and compositor |
| Portability | Windows XP+, macOS, Linux, WebAssembly | Windows 10+, macOS, Linux, mobile, embedded | Windows 10+, macOS, Linux, mobile, web | Windows 10+, macOS, Linux |
| Language | Ada | C++ | Dart | JavaScript |
| Memory safety | checked, deterministic reclamation | manual | garbage-collected | garbage-collected |
| Styling | CSS | QSS | Dart widget code | CSS |
Sizes are for a minimal application; yours grows with your own code and assets. Each of the others buys its size with a large ecosystem and years of production use — the trade Adi2 offers is a single file you can hand to someone, on hardware the others have moved past.
hello_example
material_demo
html_view_example
rlottie_example
assets_example
Full gallery of every example: docs/gallery.md. Or run them yourself, in the browser: live demos.
/* examples/css/hello_example.css */
.primary {
background-color: rgb(37, 99, 235);
border-radius: 8px;
padding: 10px 16px;
transition: background-color 150ms ease-out;
}
.primary:hover { background-color: rgb(29, 78, 216); }
.primary::label { color: white; font-size: 14px; font-weight: 500; }
<!-- examples/xml/hello_example.xml -->
<adi>
<link rel="stylesheet" href="examples/css/hello_example.css"/>
<callback name="On_Hello_Click" type="Adi.Widget.Button.Click_Callback"/>
<window title="Hello, Adi" width="320" height="180">
<box class="root">
<label text="Welcome to Adi" class="welcome"/>
<button text="Click me" class="primary" on-clicked="On_Hello_Click"/>
</box>
</window>
</adi>
The toolchain emits a typed Ada package you instantiate from your main — see examples/hello_example.adb for the full ~25-line program.
The CSS rule above is just an aggregate. The XML widget tree is just a few constructor calls. Both paths land on the same API — see examples/hello_raw_example.adb for the full equivalent program. The shape of the styling code is:
function Style return Style_Builder renames Adi.Widget_Styles.Create;
-- Equivalent of .primary base + :hover from hello_example.css
Primary_Base : constant Style_Rules :=
(Background_Color => Set_Bg (RGB (37, 99, 235)),
Border_Radius => Set (Radius (Px (8.0))),
Padding => Set (CSS_Box (Px (10.0), Px (16.0))),
Transition => Set ((Duration => 0.15,
Easing => Ease_Out,
Properties => Props (Prop_Background_Color))),
others => <>);
Primary_Hover : constant Style_Rules :=
(Background_Color => Set_Bg (RGB (29, 78, 216)),
others => <>);
-- Wire base + hover to the button's Main_Part
Set_Part_Style (Widget_Handle'(+Btn), Main_Part,
Style.Base (Primary_Base).On_Hover (Primary_Hover).Build);
Build and run either flavour:
tools/build_examples.sh hello_example hello_raw_example
./examples/bin/hello_example # XML + CSS pipeline
./examples/bin/hello_raw_example # pure hand-written Ada
# Build the library
alr build -- -j0
# Build and run the test suite
tools/run_tests.sh
# Build all example programs
tools/build_examples.sh
# ...or just one
tools/build_examples.sh stack_example
# Try a demo
./examples/bin/material_demo
./examples/bin/html_view_example
To use Adi2 from your own project, with "adi.gpr" — SDL linker options come with it. The library's public specs use Ada 2022 constructs, so units that with Adi.* packages need pragma Ada_2022; or -gnat2022.
Starting your own project? docs/getting_started.md walks from an empty directory to a working window, in XML/CSS and again in plain Ada.
Full build instructions, including building without Alire, in docs/build.md and docs/gprbuild_without_alire.md.
Companion crates under extras/. Each is its own Alire crate
with its own dependencies, so the library never acquires them.
opengl_demo
A tetrahedron drawn by OpenGL into a texture the application owns, shown
through a texture-view widget and driven by ordinary Adi sliders and
switches. Adi issues no GL call and never destroys the texture: it is
handed the texture's name and blits it where the layout put the widget,
under the same clipping and opacity as anything else.
cd extras/opengl_demo
./gen.sh # Ada from the crate's XML and CSS
alr build
./bin/gl_triangle
How the widget works, and the other ways to hand it a surface —
Direct3D, Vulkan, or plain CPU pixels — in
docs/texture_view.md.
CSS.
HTML view.
table, tr, td/th, column widths, spanning.display: flex and display: grid inside the document.Widgets and themes.
Input and interaction.
Text and reach.
direction and bidi reordering.Portability.
Authoring and tooling.
gnatdoc.Correctness and API.
Pre/Post/Type_Invariant and SPARK-mode subsets.Have an idea? Open an issue (see CONTRIBUTING.md for the policy).
Tested on GNU/Linux, Windows (XP, 7, 8, 10, 11, via MinGW), macOS, and WebAssembly (Emscripten). Anywhere else GNAT and SDL3 build should follow — the BSDs among them.
Rendering goes through the SDL renderer abstraction, so it takes hardware acceleration where the machine offers it and falls back to software where it does not. That is what puts the same binary on Windows XP and on a current desktop.
Why "Adi2"? And why is the Ada package still Adi.*?
"adi" is too common a word for search engines — Adi2 is findable. The in-code namespace stays Adi.* because with Adi.Widget.Button; reads better than Adi2.Widget.Button and renaming it would churn every source file for zero functional gain. Project = Adi2, package = Adi.
A Native, Portable GUI Framework for Ada — 3rd Ada Developers Workshop, AEiC 2026, 13 June 2026. Building an Adi2 application, and driving the running UI from an LLM through the MCP bridge.
| Topic | Doc |
|---|---|
| Your first Adi2 application | docs/getting_started.md |
| High-level architecture and core components | docs/architecture.md |
| CSS styling — selectors, properties, runtime API, codegen | docs/css_styling.md |
| Declarative XML UIs and the widget grammar | docs/xml_ui_system.md |
| HTML view widget specification | docs/html_view_spec.md |
| Texture view — showing a surface your app drew on the GPU | docs/texture_view.md |
| Static asset bundling (single-binary deployments) | docs/static_assets.md |
Internationalization, plurals, .po compilation | docs/i18n.md |
| Settings store with JSON backend | docs/settings.md |
| OS integration — dialogs, clipboard, paths | docs/os_integration.md |
| Signals and deferred dispatch | docs/signals.md |
| Antialiased rendering primitives | docs/rendering_aa.md |
| MCP runtime introspection and interaction | docs/mcp.md |
| Handle ownership model | docs/handle_ownership.md |
| Coding conventions | docs/coding_conventions.md |
| Adding a CSS property / example / test | docs/adding_css_property.md, docs/adding_example.md, docs/adding_test.md |
Issues and pull requests welcome.
Before beginning a new feature, a change in behaviour, or a substantial
refactoring, open an issue so that the proposed approach can be
discussed. Follow the existing code style
(docs/coding_conventions.md), keep the
tests green, and add tests for new behaviour.
Adi2 is licensed under Apache-2.0. See
CONTRIBUTING.md for the
contributor licensing terms, including when acceptance of the
Contributor License Agreement is required.
Adi2 is independently developed and maintained. Sponsorship funds ongoing maintenance, cross-platform testing, documentation, and work on the public roadmap.
Organisations interested in supporting the project, or in funding a specific feature, port, or integration: adi@aldustechnology.com.
Sponsorship supports the project as a whole. Guaranteed response times or delivery commitments require a separate commercial agreement.
Apache-2.0. See LICENSE.
Every file in the repository carries a declared licence and copyright, checked in CI against the REUSE specification. REUSE.toml holds the declarations and LICENSES/ the full text of every licence in use; reuse spdx will produce an SPDX bill of materials from them.
Vendored third-party code under vendor/ is mostly permissive — MIT, Apache-2.0, BSD-style, OFL. Two obligations do not follow automatically from shipping that inventory, and apply to anyone distributing a binary built from this source:
vendor/rlottie/src/vector/freetype/ and plutovg's plutovg-ft-* files are under the FreeType Licence, and Adi2 links them statically. A binary distribution must state in its documentation that the software is based in part of the work of the FreeType Team. Redistributing the source instead requires retaining FTL.TXT unaltered, preserving the original copyright notices, and marking any changes.vendor/rlottie/src/vector/vinterpolator.cpp is file-level copyleft. Distributing a build that contains it obliges telling recipients how to obtain that file's source form; modifications to it must be made available under the same licence.Example assets under examples/assets/ are demonstration content rather than part of the library; those with known third-party terms are attributed in examples/assets/NOTICE.md.
Adi2 is written by Aldo Nicolas Bruno. Report bugs and propose features through the issue tracker. For private enquiries, sponsored development, or commercial support: adi@aldustechnology.com.
583 commits
Ada
88.6%
Python
9.9%
A modern GUI library for Ada.
Adi2 gives you a real widget toolkit with the niceties developers expect from a modern UI stack — CSS-like styling with live reload, declarative XML layouts, animations, SVG and Lottie graphics, internationalization, and asset bundling — implemented natively in Ada on top of SDL3.
Status: in production use, but not yet a stable release — APIs may still change between versions.
.css syntax. Edit the file, save, see the change. No recompile during development. Prefer pure Ada? CSS rules are just plain Ada aggregates of Style_Rules — write them by hand with no extra ceremony (see the snippet below).<button>, <grid>, <text-editor> in XML and let the toolchain emit clean Ada packages, or construct the same widget tree directly in Ada with handle-based builders. Both paths target the exact same API; the XML generator is a convenience, not a requirement..po → Ada compilation.color, background-color, border-color, border-width, border-radius, padding, margin, opacity, box-shadow and font-size — the framework handles interpolation and timing.dp/dip for layout, rem for typography, pix when you mean one renderer pixel exactly, and px — which follows the display scale or not, depending on Set_Px_Maps_To_Dip. See docs/css_styling.md.wasm/ for the build.A release build links statically into a single executable under 10 MB — the widget toolkit, the CSS engine, SVG and Lottie rendering, all of it. Whatever assets you bundle add their own weight to that.
It draws through SDL's renderer, which binds to whatever the host offers: Direct3D on Windows, Metal on macOS, Vulkan or OpenGL where they exist, software as the floor. Windows XP takes Direct3D 9 and a current Mac takes Metal, from the same source.
| Adi2 | Qt | Flutter | Electron | |
|---|---|---|---|---|
| Ship size | <10 MB, one file | ~15–30 MB static; otherwise a Qt runtime alongside | ~20 MB+, engine plus a data directory | ~100 MB+, bundling Chromium and Node |
| Runtime | self-contained | Qt libraries and plugins | Flutter engine; GTK3 on Linux | Chromium and Node |
| Graphics | SDL renderer, software fallback included | GPU or raster backends | Skia or Impeller, GPU expected | GPU stack and compositor |
| Portability | Windows XP+, macOS, Linux, WebAssembly | Windows 10+, macOS, Linux, mobile, embedded | Windows 10+, macOS, Linux, mobile, web | Windows 10+, macOS, Linux |
| Language | Ada | C++ | Dart | JavaScript |
| Memory safety | checked, deterministic reclamation | manual | garbage-collected | garbage-collected |
| Styling | CSS | QSS | Dart widget code | CSS |
Sizes are for a minimal application; yours grows with your own code and assets. Each of the others buys its size with a large ecosystem and years of production use — the trade Adi2 offers is a single file you can hand to someone, on hardware the others have moved past.
hello_example
material_demo
html_view_example
rlottie_example
assets_example
Full gallery of every example: docs/gallery.md. Or run them yourself, in the browser: live demos.
/* examples/css/hello_example.css */
.primary {
background-color: rgb(37, 99, 235);
border-radius: 8px;
padding: 10px 16px;
transition: background-color 150ms ease-out;
}
.primary:hover { background-color: rgb(29, 78, 216); }
.primary::label { color: white; font-size: 14px; font-weight: 500; }
<!-- examples/xml/hello_example.xml -->
<adi>
<link rel="stylesheet" href="examples/css/hello_example.css"/>
<callback name="On_Hello_Click" type="Adi.Widget.Button.Click_Callback"/>
<window title="Hello, Adi" width="320" height="180">
<box class="root">
<label text="Welcome to Adi" class="welcome"/>
<button text="Click me" class="primary" on-clicked="On_Hello_Click"/>
</box>
</window>
</adi>
The toolchain emits a typed Ada package you instantiate from your main — see examples/hello_example.adb for the full ~25-line program.
The CSS rule above is just an aggregate. The XML widget tree is just a few constructor calls. Both paths land on the same API — see examples/hello_raw_example.adb for the full equivalent program. The shape of the styling code is:
function Style return Style_Builder renames Adi.Widget_Styles.Create;
-- Equivalent of .primary base + :hover from hello_example.css
Primary_Base : constant Style_Rules :=
(Background_Color => Set_Bg (RGB (37, 99, 235)),
Border_Radius => Set (Radius (Px (8.0))),
Padding => Set (CSS_Box (Px (10.0), Px (16.0))),
Transition => Set ((Duration => 0.15,
Easing => Ease_Out,
Properties => Props (Prop_Background_Color))),
others => <>);
Primary_Hover : constant Style_Rules :=
(Background_Color => Set_Bg (RGB (29, 78, 216)),
others => <>);
-- Wire base + hover to the button's Main_Part
Set_Part_Style (Widget_Handle'(+Btn), Main_Part,
Style.Base (Primary_Base).On_Hover (Primary_Hover).Build);
Build and run either flavour:
tools/build_examples.sh hello_example hello_raw_example
./examples/bin/hello_example # XML + CSS pipeline
./examples/bin/hello_raw_example # pure hand-written Ada
# Build the library
alr build -- -j0
# Build and run the test suite
tools/run_tests.sh
# Build all example programs
tools/build_examples.sh
# ...or just one
tools/build_examples.sh stack_example
# Try a demo
./examples/bin/material_demo
./examples/bin/html_view_example
To use Adi2 from your own project, with "adi.gpr" — SDL linker options come with it. The library's public specs use Ada 2022 constructs, so units that with Adi.* packages need pragma Ada_2022; or -gnat2022.
Starting your own project? docs/getting_started.md walks from an empty directory to a working window, in XML/CSS and again in plain Ada.
Full build instructions, including building without Alire, in docs/build.md and docs/gprbuild_without_alire.md.
Companion crates under extras/. Each is its own Alire crate
with its own dependencies, so the library never acquires them.
opengl_demo
A tetrahedron drawn by OpenGL into a texture the application owns, shown
through a texture-view widget and driven by ordinary Adi sliders and
switches. Adi issues no GL call and never destroys the texture: it is
handed the texture's name and blits it where the layout put the widget,
under the same clipping and opacity as anything else.
cd extras/opengl_demo
./gen.sh # Ada from the crate's XML and CSS
alr build
./bin/gl_triangle
How the widget works, and the other ways to hand it a surface —
Direct3D, Vulkan, or plain CPU pixels — in
docs/texture_view.md.
CSS.
HTML view.
table, tr, td/th, column widths, spanning.display: flex and display: grid inside the document.Widgets and themes.
Input and interaction.
Text and reach.
direction and bidi reordering.Portability.
Authoring and tooling.
gnatdoc.Correctness and API.
Pre/Post/Type_Invariant and SPARK-mode subsets.Have an idea? Open an issue (see CONTRIBUTING.md for the policy).
Tested on GNU/Linux, Windows (XP, 7, 8, 10, 11, via MinGW), macOS, and WebAssembly (Emscripten). Anywhere else GNAT and SDL3 build should follow — the BSDs among them.
Rendering goes through the SDL renderer abstraction, so it takes hardware acceleration where the machine offers it and falls back to software where it does not. That is what puts the same binary on Windows XP and on a current desktop.
Why "Adi2"? And why is the Ada package still Adi.*?
"adi" is too common a word for search engines — Adi2 is findable. The in-code namespace stays Adi.* because with Adi.Widget.Button; reads better than Adi2.Widget.Button and renaming it would churn every source file for zero functional gain. Project = Adi2, package = Adi.
A Native, Portable GUI Framework for Ada — 3rd Ada Developers Workshop, AEiC 2026, 13 June 2026. Building an Adi2 application, and driving the running UI from an LLM through the MCP bridge.
| Topic | Doc |
|---|---|
| Your first Adi2 application | docs/getting_started.md |
| High-level architecture and core components | docs/architecture.md |
| CSS styling — selectors, properties, runtime API, codegen | docs/css_styling.md |
| Declarative XML UIs and the widget grammar | docs/xml_ui_system.md |
| HTML view widget specification | docs/html_view_spec.md |
| Texture view — showing a surface your app drew on the GPU | docs/texture_view.md |
| Static asset bundling (single-binary deployments) | docs/static_assets.md |
Internationalization, plurals, .po compilation | docs/i18n.md |
| Settings store with JSON backend | docs/settings.md |
| OS integration — dialogs, clipboard, paths | docs/os_integration.md |
| Signals and deferred dispatch | docs/signals.md |
| Antialiased rendering primitives | docs/rendering_aa.md |
| MCP runtime introspection and interaction | docs/mcp.md |
| Handle ownership model | docs/handle_ownership.md |
| Coding conventions | docs/coding_conventions.md |
| Adding a CSS property / example / test | docs/adding_css_property.md, docs/adding_example.md, docs/adding_test.md |
Issues and pull requests welcome.
Before beginning a new feature, a change in behaviour, or a substantial
refactoring, open an issue so that the proposed approach can be
discussed. Follow the existing code style
(docs/coding_conventions.md), keep the
tests green, and add tests for new behaviour.
Adi2 is licensed under Apache-2.0. See
CONTRIBUTING.md for the
contributor licensing terms, including when acceptance of the
Contributor License Agreement is required.
Adi2 is independently developed and maintained. Sponsorship funds ongoing maintenance, cross-platform testing, documentation, and work on the public roadmap.
Organisations interested in supporting the project, or in funding a specific feature, port, or integration: adi@aldustechnology.com.
Sponsorship supports the project as a whole. Guaranteed response times or delivery commitments require a separate commercial agreement.
Apache-2.0. See LICENSE.
Every file in the repository carries a declared licence and copyright, checked in CI against the REUSE specification. REUSE.toml holds the declarations and LICENSES/ the full text of every licence in use; reuse spdx will produce an SPDX bill of materials from them.
Vendored third-party code under vendor/ is mostly permissive — MIT, Apache-2.0, BSD-style, OFL. Two obligations do not follow automatically from shipping that inventory, and apply to anyone distributing a binary built from this source:
vendor/rlottie/src/vector/freetype/ and plutovg's plutovg-ft-* files are under the FreeType Licence, and Adi2 links them statically. A binary distribution must state in its documentation that the software is based in part of the work of the FreeType Team. Redistributing the source instead requires retaining FTL.TXT unaltered, preserving the original copyright notices, and marking any changes.vendor/rlottie/src/vector/vinterpolator.cpp is file-level copyleft. Distributing a build that contains it obliges telling recipients how to obtain that file's source form; modifications to it must be made available under the same licence.Example assets under examples/assets/ are demonstration content rather than part of the library; those with known third-party terms are attributed in examples/assets/NOTICE.md.
Adi2 is written by Aldo Nicolas Bruno. Report bugs and propose features through the issue tracker. For private enquiries, sponsored development, or commercial support: adi@aldustechnology.com.
583 commits
Ada
88.6%
Python
9.9%