Skip to content

A2UI Migration Guide

This guide helps you migrate from other UI approaches to the A2UI component system.

A2UI (App-to-UI) is a declarative, platform-agnostic UI system that:

  • Renders natively on web, desktop, and mobile
  • Supports real-time streaming updates
  • Integrates with flow-based architectures
  • Enables AI-assisted UI generation

From React Components

Convert React JSX to A2UI JSON structures.

From HTML/CSS

Transform static markup to A2UI components.

From Custom JSON

Map your schema to A2UI format.

From Figma

Export Figma designs as A2UI.


<div className="p-4 bg-white rounded-lg shadow">
<h2 className="text-xl font-bold">{title}</h2>
<p className="text-gray-600">{description}</p>
<button onClick={handleClick}>
Click me
</button>
</div>
ReactA2UI Equivalent
<div>Column, Row, or Stack
<span>Text
<h1>-<h6>Text with variant prop
<p>Text
<img>Image
<button>Button
<input type="text">TextField
<input type="checkbox">Checkbox
<input type="radio">RadioGroup
<select>Select
<ul>/<ol>List
<form>Column with form handling
const handleSubmit = (e) => {
e.preventDefault();
submitForm(formData);
};
<form onSubmit={handleSubmit}>
<input
value={name}
onChange={(e) => setName(e.target.value)}
/>
<button type="submit">Submit</button>
</form>
{isLoading && <Spinner />}
{error && <ErrorMessage error={error} />}
{data && <DataDisplay data={data} />}
<ul>
{items.map((item) => (
<li key={item.id}>
<span>{item.name}</span>
<button onClick={() => deleteItem(item.id)}>
Delete
</button>
</li>
))}
</ul>

<div class="card">
<div class="card-header">
<img src="avatar.jpg" class="avatar">
<div class="user-info">
<h3 class="user-name">John Doe</h3>
<span class="user-role">Developer</span>
</div>
</div>
<div class="card-body">
<p>User description here...</p>
</div>
<div class="card-footer">
<button class="btn btn-primary">Follow</button>
</div>
</div>

A2UI uses Tailwind CSS classes. Common conversions:

CSS PropertyTailwind Class
margin: 16pxm-4
padding: 24pxp-6
display: flexflex
flex-direction: columnflex-col
justify-content: space-betweenjustify-between
align-items: centeritems-center
gap: 8pxgap-2
border-radius: 8pxrounded-lg
font-size: 18pxtext-lg
font-weight: boldfont-bold
color: #graytext-gray-500
background: whitebg-white

A2UI uses a data path system instead of component state:

const [count, setCount] = useState(0);
<button onClick={() => setCount(c => c + 1)}>
Count: {count}
</button>
const [form, setForm] = useState({
email: '',
password: ''
});
<input
type="email"
value={form.email}
onChange={(e) => setForm({
...form,
email: e.target.value
})}
/>

  1. Audit Your Components

    List all components that need migration. Prioritize:

    • High-usage components
    • Simple, self-contained components
    • Components without complex state
  2. Map Data Requirements

    Document what data each component needs:

    • Props received from parents
    • Internal state
    • External data (API, context)
  3. Design Data Paths

    Create a data path schema:

    /user/name
    /user/email
    /form/email
    /form/password
    /ui/isModalOpen
    /items/0/name
  4. Convert Components

    Start with leaf components (no children), then work up:

    • Convert structure to A2UI JSON
    • Map CSS/styles to Tailwind classes
    • Replace event handlers with actions
    • Add data bindings
  5. Set Up Actions

    Map interactions to A2UI actions:

    • Click handlers → onClick actions
    • Form changes → onChange with update
    • Submissions → submit actions
    • Navigation → navigate actions
  6. Test and Validate

    • Verify visual appearance matches
    • Test all interactions
    • Check responsive behavior
    • Validate data flows correctly

const [isOpen, setIsOpen] = useState(false);
<button onClick={() => setIsOpen(true)}>Open</button>
<Modal open={isOpen} onClose={() => setIsOpen(false)}>
<ModalContent>...</ModalContent>
</Modal>
const [activeTab, setActiveTab] = useState('tab1');
<Tabs value={activeTab} onChange={setActiveTab}>
<Tab value="tab1">Tab 1</Tab>
<Tab value="tab2">Tab 2</Tab>
</Tabs>
<TabPanel value="tab1">Content 1</TabPanel>
<TabPanel value="tab2">Content 2</TabPanel>