# Radio
**Category**: react
**URL**: https://www.heroui.com/docs/react/migration/radio
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/migration/(components)/radio.mdx
> Migration guide for Radio from HeroUI v2 to v3
***
Refer to the [v3 Radio documentation](/docs/react/components/radio-group) for complete API reference, styling guide, and advanced examples. This guide only focuses on migrating from HeroUI v2.
## Structure Changes
In v2, Radio used a simple structure with props:
```tsx
import { RadioGroup, Radio } from "@heroui/react";
export default function App() {
return (
London
Tokyo
);
}
```
In v3, Radio requires compound components:
```tsx
import { RadioGroup, Radio, Label, Description } from "@heroui/react";
export default function App() {
return (
Capital of Japan
);
}
```
## Key Changes
### 1. Component Structure
**v2:** Simple Radio with children as label
**v3:** Compound components: `Radio.Control`, `Radio.Indicator`, `Radio.Content`
### 2. Prop Changes
| v2 Prop | v3 Location | Notes |
|---------|-------------|-------|
| `onValueChange` | `onChange` | Renamed event handler |
| `label` (on RadioGroup) | — | Use `Label` component |
| `description` (on Radio) | — | Use `Description` component inside `Radio.Content` |
| `size` | — | Removed (use Tailwind CSS) |
| `color` | — | Removed (use Tailwind CSS) |
| `classNames` | — | Use `className` props on individual components |
| `disableAnimation` | — | Removed (animations handled differently) |
| — | `variant` | New prop on `RadioGroup`: `"primary"` (default) or `"secondary"` for lower emphasis styling |
| — | `isReadOnly` | New prop on `RadioGroup`: prevents value changes while keeping the group focusable |
## Migration Examples
### Form Validation
```tsx
{/* With description */}
London
{/* With validation */}
London
```
```tsx
import { Label, Description, FieldError } from "@heroui/react";
{/* With description */}
Capital of England
{/* With validation */}
Please select an option
```
### Controlled
```tsx
import { useState } from "react";
const [selected, setSelected] = useState("london");
London
Tokyo
```
```tsx
import { useState } from "react";
const [selected, setSelected] = useState("london");
```
### Horizontal Orientation
```tsx
London
Tokyo
```
```tsx
```
### Variants
v3 introduces a `variant` prop on `RadioGroup` with `"primary"` (default) and `"secondary"` options:
```tsx
{/* Primary variant (default) */}
{/* Secondary variant - lower emphasis, suitable for Surface components */}
```
### Read Only
v3 supports `isReadOnly` on `RadioGroup`, which prevents value changes while keeping the group focusable:
```tsx
```
## Component Anatomy
The v3 Radio follows this structure:
```
RadioGroup (Root)
├── Label (optional)
├── Radio
│ ├── Radio.Control
│ │ └── Radio.Indicator
│ └── Radio.Content
│ ├── Label
│ └── Description (optional)
└── FieldError (optional)
```
## Summary
1. **Component Structure**: Must use compound components (`Radio.Control`, `Radio.Indicator`, `Radio.Content`)
2. **Label Handling**: `label` prop removed - use `Label` component
3. **Description Handling**: `description` prop removed - use `Description` component inside `Radio.Content`
4. **Event Handler**: `onValueChange` → `onChange`
5. **Styling Props Removed**: `size`, `color` - use Tailwind CSS
6. **ClassNames Removed**: Use `className` props on individual components
7. **Error Message**: Use `FieldError` component instead of `errorMessage` prop
8. **New `variant` Prop**: `RadioGroup` supports `"primary"` (default) and `"secondary"` for lower emphasis styling
9. **New `isReadOnly` Prop**: `RadioGroup` supports `isReadOnly` to prevent value changes while keeping the group focusable