How to Contribute to the A2UI Project: A Step-by-Step Developer Guide
Contributing to A2UI requires forking the Google repository, creating a feature branch that follows Google style guides for Python or TypeScript, and submitting a pull request that passes automated linting, unit tests, and specification validation.
A2UI (Agent-to-User Interface) is an open-source framework that enables LLM agents to describe user interfaces declaratively in JSON. To successfully contribute to the A2UI project, you must understand its architecture—spanning the JSON protocol specification, transport-agnostic renderers, and language-specific SDKs—while adhering to the standardized GitHub workflow enforced by the maintainers.
Understanding the A2UI Architecture
Before writing code, study how A2UI separates concerns between agents and clients.
Declarative JSON Protocol
Agents emit JSON payloads that describe a flat list of components, each requiring an id, type, and optional properties. This contract is defined in docs/specification/v0.9-a2ui.md, which serves as the source of truth for component schemas and data binding rules. All renderer implementations must consume payloads compliant with this specification.
Renderer Pipeline and Component Registry
The Lit renderer in renderers/lit/src/0.8/ui/ demonstrates the three-stage pipeline:
- Resolution: Parsing JSON into internal model objects
- Mapping: Converting abstract types like
text-fieldto concrete UI widgets - Theming: Consuming theme objects (e.g.,
theme.components.Video) for styling
Renderers expose supported types through a ComponentRegistry located in renderers/lit/src/0.8/ui/component-registry.ts. Adding any new component requires registration here.
Data Binding Patterns
Primitive values support literal strings, literal numbers, or dynamic paths resolved via A2uiMessageProcessor. The Video component in renderers/lit/src/0.8/ui/video.ts (lines 52-80) demonstrates both direct URL literals and path-based lookups using this.processor.getData.
The Contribution Workflow
The project follows a standard GitHub pull-request model with strict quality gates.
Repository Setup and Syncing
Start by forking google/A2UI via the GitHub interface. Configure your local clone to track upstream:
git remote add upstream https://github.com/google/A2UI.git
git fetch upstream && git rebase upstream/main
Regular rebasing prevents merge conflicts against the rapidly evolving main branch.
Coding Standards and Style Guides
All submissions must comply with Google style guides:
- Python: Google Python Style Guide (enforced in
agent_sdks/python/) - TypeScript: Google TypeScript Style Guide (enforced in
renderers/lit/src/)
Every source file requires the standard Google license header. Missing headers trigger immediate CI failure.
Testing Requirements
Add or update unit tests alongside your changes. For Lit components, place tests adjacent to implementation files (e.g., badge.test.ts for badge.ts). Run the full suite locally before pushing:
npm test # For TypeScript/Lit renderers
pytest # For Python SDK changes
CI rejects PRs that break coverage thresholds or fail lint checks.
Pull Request Submission
- Create a short-lived feature branch:
git checkout -b my-feature - Write clear commit messages using the format:
<type>: <short description>\n\n<optional body> - Push to your fork and open a PR against
google/A2UI:main - Complete the PR template, linking relevant issues
- Address reviewer feedback through amended commits
The full checklist is documented in CONTRIBUTING.md.
Implementing New Components: A Practical Example
Extend the Lit renderer by adding a Badge component following the existing patterns in video.ts.
Creating the Badge Component
Create renderers/lit/src/0.8/ui/badge.ts with this implementation:
import { html, css, nothing } from "lit";
import { customElement, property } from "lit/decorators.js";
import { Root } from "./root.js";
import * as Primitives from "@a2ui/web_core/types/primitives";
import { classMap } from "lit/directives/class-map.js";
import { styleMap } from "lit/directives/style-map.js";
@customElement("a2ui-badge")
export class Badge extends Root {
@property()
accessor label: Primitives.StringValue | null = null;
static styles = [
css`
:host {
display: inline-block;
padding: 0.2em 0.5em;
border-radius: 0.5em;
background: var(--badge-bg, #e0e0e0);
color: var(--badge-fg, #000);
font-size: var(--badge-size, 0.75rem);
}
`,
];
#renderLabel() {
if (!this.label) return nothing;
if (typeof this.label === "object" && "literalString" in this.label) {
return html`${this.label.literalString}`;
}
return html`(invalid)`;
}
render() {
return html`<span
class=${classMap(this.theme.components.Badge)}
style=${this.theme.additionalStyles?.Badge
? styleMap(this.theme.additionalStyles?.Badge)
: nothing}
>${this.#renderLabel()}</span
>`;
}
}
Component Registration and Specification Updates
Register the component in renderers/lit/src/0.8/ui/component-registry.ts:
registry.register("badge", Badge);
Optionally update docs/specification/v0.9-a2ui.md to define the "badge" type with its label property schema. Add comprehensive unit tests in badge.test.ts to verify rendering logic and data binding.
Critical File Paths for Contributors
Navigate the codebase efficiently using these canonical locations:
README.md: Architecture overview and demo instructions (Restaurant Finder sample)CONTRIBUTING.md: Complete contribution checklist and CLA requirementsdocs/specification/v0.9-a2ui.md: JSON protocol schema and component catalogrenderers/lit/src/0.8/ui/video.ts: Reference implementation showing data bindingrenderers/lit/src/0.8/ui/component-registry.ts: Component registration interfaceagent_sdks/python/tests/: SDK test patterns for payload constructionsamples/restaurant_finder/: End-to-end integration examples
Summary
- Fork and sync the repository using
upstreamremote configuration to prevent merge conflicts. - Follow Google style guides strictly; missing license headers or formatting violations block CI.
- Understand the architecture: A2UI uses a declarative JSON protocol, transport-agnostic renderers, and a component registry pattern.
- Test locally using
npm testorpytestbefore submitting to avoid automated rejection. - Register components in
component-registry.tsand follow theVideocomponent pattern for data binding.
Frequently Asked Questions
What license and CLA requirements apply to A2UI contributions?
All contributors must sign the Google Contributor License Agreement (CLA) before submitting pull requests. Every file must include the standard Google open-source license header. The full legal requirements are detailed in CONTRIBUTING.md at the repository root.
How do I add support for a new UI component type in A2UI?
Create a concrete implementation in the appropriate renderer directory (e.g., renderers/lit/src/0.8/ui/), extend the base Root class, and register the component in component-registry.ts. Update the protocol specification in docs/specification/v0.9-a2ui.md if introducing new schema elements, and provide unit tests following the patterns in video.ts or agent_sdks/python/tests/.
Why does my pull request fail automated checks?
CI failures typically result from three issues: missing Google license headers, style guide violations (enforced by npm run lint or equivalent), or insufficient test coverage. The repository runs GitHub Actions that validate the specification schema, lint all TypeScript and Python code, and execute unit tests. Run these checks locally before pushing to identify failures early.
Which renderer should I use as a reference when contributing new components?
The Lit renderer serves as the reference web implementation. Study renderers/lit/src/0.8/ui/video.ts to understand how components handle literal values versus dynamic data paths via A2uiMessageProcessor. This implementation demonstrates the theming system, property binding, and the integration points required for the ComponentRegistry.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →