Open-source project
AccessKit/accesskit avatar
AccessKit/accesskit

AccessKit: one accessibility tree schema, five platform adapters

Accessibility infrastructure for UI toolkits

1,546 stars126 forksRustBSD-3-Clause

At a glance

What is it?
AccessKit gives UI toolkits a cross-platform, cross-language accessibility abstraction so a toolkit implements accessibility once instead of once per platform. The cost is a Rust-first design, a feature set that stops short of rich text, and a web adapter that does not exist yet.
Who is it for?
AccessKit suits developers of custom-drawn or immediate-mode toolkits who would otherwise hand-write Android, iOS, macOS, Unix and Windows accessibility code and keep it in sync. It does not suit a team that needs rich text or hypertext exposed to screen readers today, or one that renders its interface to a canvas on the web, since the web adapter is still planned.
Can I use it commercially?
Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 5 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The tree schema is the product, not the platform code

AccessKit targets a narrow audience: authors of toolkits that render their own UI elements rather than shipping stock widgets. The problem it names is that such a toolkit must implement accessibility separately for every platform it supports. The centre of the project is a data schema describing everything needed to render an accessible interface. It is a tree in which each node is one UI element or an element cluster such as a window or document, carrying an integer ID, a role such as button, label or text input, and a set of optional attributes. The schema also defines the actions assistive technology can request, including moving keyboard focus, invoking a button and selecting text. The README notes the model is based largely on Chromium's cross-platform accessibility abstraction, so the vocabulary is familiar to anyone who has worked on Chromium.

Why the tree is pushed to the adapter instead of pulled on demand

The interaction between a toolkit and a platform adapter copies another Chromium habit. Chromium cannot pull accessibility data synchronously from a sandboxed renderer, so the renderer pushes a full tree once and then incremental updates, and the browser side sends a request back only when assistive technology invokes an action. AccessKit inverts nothing about that shape, with one important difference: the adapter and the toolkit both live in the same process and talk through ordinary function calls instead of IPC. The consequence shows up in memory. Only the platform adapter retains a complete accessibility tree, which is what makes the design usable for immediate-mode toolkits, where no persistent widget objects exist to walk, as long as the toolkit can produce a stable ID for each element.

The Cargo workspace splits schema, adapters and examples

The repository layout is the clearest statement of the architecture. The root Cargo.toml declares a workspace with resolver 3, and its members name the schema crate, the consumer crate and one directory per adapter, plus a shared example crate. Default members are narrower still, which is what a plain `cargo build` at the root will compile:

toml
[workspace]
resolver = "3"
members = [
    "accesskit",
    "accesskit_consumer",
    "adapters/android",
    "adapters/atspi-common",
    "adapters/ios",
    "adapters/macos",
    "adapters/unix",
    "adapters/windows",
    "adapters/winit",
    "example_common",
]
default-members = [
    "accesskit",
    "accesskit_consumer",
    "adapters/winit",
]

The README documents no install command for the project itself. Each adapter is a published crate, so a toolkit takes it as a Cargo dependency, and toolkit authors working in C or Python pick up the generated bindings instead. Examples live in the shared example crate, with a Windows example using the Win32 API directly, a cross-platform example using SDL, and a Pygame example for Python.

Rust is the source of truth and the bindings follow it

The canonical schema is written in Rust, chosen for efficiency and an expressive type system, and representations in other languages or schema languages such as JSON Schema or Protocol Buffers are generated from that code. Runtime data transfer follows the same logic. When the toolkit is written in Rust, or in a language that can call into Rust cheaply such as C or C++, schema data passes back and forth with no serialization at all. Elsewhere serialization is used to keep language interoperability cheap, and because the schema supports serde, each binding picks its own format. Bindings are thin: the C API is implemented directly in Rust with its header generated by cbindgen, and the Python bindings use PyO3 and are published on PyPI under the accesskit name.

Five adapters ship, and they stop short of rich text

The released adapters cover Android through the Java-based accessibility API, iOS through UIAccessibility in UIKit, macOS through NSAccessibility in AppKit, Unix through AT-SPI D-Bus interfaces using zbus, and Windows through UI Automation. The winit adapter is described as the recommended way to use AccessKit with the winit windowing library. The README is unusually blunt about coverage: the adapters are at rough feature parity, they do not yet support all element types or all schema properties, and they do not yet support rich text or hypertext. Single-line and multi-line text input controls are covered. For a toolkit whose selling point is a text editor or a document view, that gap is the whole decision, not a footnote.

The web adapter is the missing platform

The planned list contains one entry: web, for applications that render their own UI elements to a canvas. Everything else on the platform list is released, which means a canvas based web application has no adapter to depend on and no stated timeline to plan against. The consumer crate covers a different gap: platform-independent code the adapters share, useful for embedded assistive technology such as a screen reader running inside the application, on devices with no platform accessibility support at all such as game consoles and appliances. The README also states plainly that comprehensive documentation, including a conceptual introduction for developers new to accessibility, still has to be written.

Against writing to each platform API yourself

The alternative is direct work: hand-write against NSAccessibility, UI Automation, the Android accessibility API, UIAccessibility and AT-SPI, then keep the five implementations consistent as the app evolves. The difference in approach is where the effort sits. Direct work puts all of it in the application and leaves every platform quirk visible in your own code, which makes debugging easier but multiplies maintenance. AccessKit collapses that into one tree and a set of adapters, and adds a push model where the platform model is usually pull. The trade is a Rust dependency in a stack that may not otherwise have one, plus accepting a schema whose coverage stops short of rich text. Recent releases show the adapters published together on 2026-09-25, and the root manifest pins edition 2024 with a Rust floor of 1.87.

Editorial conclusion

AccessKit suits developers of custom-drawn or immediate-mode toolkits who would otherwise hand-write Android, iOS, macOS, Unix and Windows accessibility code and keep it in sync. It does not suit a team that needs rich text or hypertext exposed to screen readers today, or one that renders its interface to a canvas on the web, since the web adapter is still planned. Verify first that the platform you ship on has a released adapter with the element types and properties you need, and that your toolkit can hand out a stable integer ID per element, because that requirement decides whether the pushed-tree design fits you at all. The Rust floor is 1.87, the last push was on 2026-10-14, and the repository is not archived.

Frequently asked questions

Which platforms does AccessKit support today?

Released adapters exist for Android, iOS, macOS, Unix through AT-SPI and Windows through UI Automation, plus a winit adapter for the winit windowing library. A web adapter for canvas rendering applications is listed as planned.

Do I have to write my toolkit in Rust to use AccessKit?

No. The README states that toolkit developers should not be required to use Rust directly, and provides C bindings with a cbindgen generated header and Python bindings built with PyO3.

Does AccessKit support rich text and hypertext?

Not yet. The README says the adapters do not yet support rich text or hypertext, though single-line and multi-line text input controls are covered.

Official sources

  1. AccessKit/accesskit on GitHub
  2. License: BSD-3-Clause
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/accesskit-accesskit.svg)](https://hysenlabs.com/projects/accesskit-accesskit)

Was this useful?