# Migration Guide
Guide for upgrading between versions and migrating from manual GPUI code.
## Migrating from Manual GPUI
### Benefits of GPUI-RSX
- **More concise**: Less boilerplate code
- **Better readability**: HTML-like structure is easier to understand
- **Familiar syntax**: JSX-like for those coming from React
- **Type safe**: Full Rust type checking
- **No runtime overhead**: Compiles to the same GPUI code
### Basic Element Migration
**Before (Manual GPUI):**
```rust
div()
.flex()
.flex_col()
.gap(px(16.0))
.bg(rgb(0x3b82f6))
```
**After (GPUI-RSX):**
```rust
rsx! {
<div class="flex flex-col gap-4 bg-blue-500" />
}
```
### Children Migration
**Before (Manual GPUI):**
```rust
div()
.child("Hello")
.child(span().child("World"))
.child(button().child("Click"))
```
**After (GPUI-RSX):**
```rust
rsx! {
<div>
"Hello"
<span>"World"</span>
<button>"Click"</button>
</div>
}
```
### Event Handlers
**Before (Manual GPUI):**
```rust
button()
.on_click(cx.listener(|view, _event, cx| {
view.count += 1;
cx.notify();
}))
.child("Click")
```
**After (GPUI-RSX):**
```rust
rsx! {
<button onClick={cx.listener(|view, _event, cx| {
view.count += 1;
cx.notify();
})}>
"Click"
</button>
}
```
### Conditional Rendering
**Before (Manual GPUI):**
```rust
let mut element = div();
if show_message {
element = element.child("Message visible");
}
element
```
**After (GPUI-RSX):**
```rust
rsx! {
<div>
{if show_message {
rsx! { <span>"Message visible"</span> }
}}
</div>
}
```
Or use `when` attribute:
```rust
rsx! {
<div
when={(show_message, |el| el.child("Message visible"))}
/>
}
```
### Lists
**Before (Manual GPUI):**
```rust
let mut list = div().flex().flex_col();
for item in &self.items {
list = list.child(
div()
.child(item.name.clone())
);
}
list
```
**After (GPUI-RSX):**
```rust
rsx! {
<div class="flex flex-col">
{for item in &self.items {
<div>{item.name.as_str()}</div>
}}
</div>
}
```
### Complex Nested Structures
**Before (Manual GPUI):**
```rust
div()
.flex()
.child(
div()
.w(px(200.0))
.bg(rgb(0xf3f4f6))
.child(
div()
.p(px(16.0))
.child("Sidebar")
)
)
.child(
div()
.flex_1()
.child(
div()
.p(px(16.0))
.child("Main content")
)
)
```
**After (GPUI-RSX):**
```rust
rsx! {
<div flex>
<div class="w-48 bg-gray-100">
<div class="p-4">"Sidebar"</div>
</div>
<div flex_1>
<div class="p-4">"Main content"</div>
</div>
</div>
}
```
### Method Chaining
Both styles can coexist:
```rust
rsx! {
<div class="flex">
{div()
.flex_1()
.bg(self.compute_color())
.child("Mixed style")}
</div>
}
```
## Version Migrations
### 0.1.0 → 0.1.1
**Changes:**
- Added `when` and `whenSome` attributes
- Added `styled` flag for semantic HTML tags
- Improved error messages
**Migration steps:**
1. **No breaking changes** - all 0.1.0 code continues to work
2. **Optional: Use new `when` attribute:**
Before:
```rust
<div>
{if condition {
rsx! { <div bg={color} /> }
} else {
rsx! { <div /> }
}}
</div>
```
After:
```rust
<div when={(condition, |el| el.bg(color))} />
```
3. **Optional: Use `styled` flag:**
Before:
```rust
<h1 class="text-3xl font-bold">"Title"</h1>
```
After:
```rust
<h1 styled>"Title"</h1>
```
### 0.1.1 → 0.1.2
**Changes:**
- Improved compile-time performance
- Better type inference
- Enhanced error messages with helpful hints
**Migration steps:**
1. **No breaking changes** - all 0.1.1 code continues to work
2. **Optional: Update Cargo.toml:**
```toml
[dependencies]
gpui-rsx = "0.1.2"
```
3. **Optional: Simplify code with better type inference:**
The macro now generates more efficient code automatically - no changes needed.
## Best Practices for Migration
### Incremental Migration
Don't migrate everything at once. Start with:
1. **New components** - Use RSX for all new code
2. **Simple components** - Migrate straightforward components first
3. **Complex components** - Migrate as you gain confidence
### Hybrid Approach
You can mix RSX and manual GPUI:
```rust
impl Render for MyView {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
rsx! {
<div>
{self.legacy_method()} // Manual GPUI
<div>"New RSX content"</div>
</div>
}
}
}
fn legacy_method(&self) -> impl IntoElement {
div().child("Legacy code")
}
```
### Testing Migration
1. **Visual testing**: Ensure UI looks the same
2. **Behavior testing**: Verify interactions work
3. **Performance testing**: Check for regressions
### Common Migration Patterns
#### Pattern 1: Simple Replacement
Before:
```rust
div().child("Hello")
```
After:
```rust
rsx! { <div>"Hello"</div> }
```
#### Pattern 2: Variable Interpolation
Before:
```rust
div().child(format!("Count: {}", count))
```
After:
```rust
rsx! { <div>{format!("Count: {}", count)}</div> }
```
#### Pattern 3: Builder Pattern to Attributes
Before:
```rust
div()
.w(px(200.0))
.h(px(100.0))
.bg(rgb(0xff0000))
```
After:
```rust
rsx! {
<div
w={px(200.0)}
h={px(100.0)}
bg={rgb(0xff0000)}
/>
}
```
#### Pattern 4: Dynamic Children
Before:
```rust
let mut container = div();
for item in items {
container = container.child(div().child(item));
}
container
```
After:
```rust
rsx! {
<div>
{for item in items {
<div>{item}</div>
}}
</div>
}
```
## Troubleshooting Migration
### Type Mismatches
If you get type errors after migration:
```rust
// Add explicit type annotations
let items: &[Item] = &self.items;
rsx! {
<div>
{for item in items {
<div>{item.render()}</div>
}}
</div>
}
```
### Performance Regressions
If performance degrades:
1. **Use references instead of clones:**
```rust
{for item in &items {
<div>{item.name.as_str()}</div>
}}
```
2. **Extract static content:**
```rust
fn static_header() -> impl IntoElement {
rsx! { <header>"Static"</header> }
}
```
3. **Batch state updates:**
```rust
self.field1 = value1;
self.field2 = value2;
cx.notify(); ```
### Compile Time Increases
If compile times increase significantly:
1. **Split large RSX blocks** into smaller methods
2. **Use incremental compilation:** `cargo build` for development
3. **Consider caching:** Results are cached between builds
## GPUI Version Compatibility
GPUI-RSX aims to stay compatible with the latest stable GPUI release.
### Checking Compatibility
```bash
### Updating Dependencies
```bash
cargo update
cargo build
```
### Version Matrix
| 0.1.0 - 0.1.2 | 0.1.x |
| Future releases | Will maintain compatibility |
## Getting Help
If you encounter issues during migration:
1. **Review documentation:**
- [Getting Started](getting-started.md)
- [API Reference](api-reference.md)
- [Best Practices](best-practices.md)
3. **Ask for help:**
- [GitHub Issues](https://github.com/wsafight/gpui-rsx/issues)
- Include: version numbers, minimal code example, error messages
## Migration Checklist
- [ ] Updated `Cargo.toml` with `gpui-rsx` dependency
- [ ] Imported `rsx` macro: `use gpui_rsx::rsx;`
- [ ] Tested simple component migration
- [ ] Migrated event handlers
- [ ] Migrated conditional rendering
- [ ] Migrated list rendering
- [ ] Tested UI appearance
- [ ] Tested interactions
- [ ] Verified performance
- [ ] Updated tests
- [ ] Updated documentation