Legacy → ui-react migration
Migrate from @acronis-platform/shadcn-uikit to @acronis-platform/ui-react with component mapping and codemod recipes.
Legacy → ui-react migration guide
This guide helps you migrate from:
@acronis-platform/shadcn-uikit(legacy)
To:
@acronis-platform/ui-react(next generation)
ui-react component ladder tracking
Docs coverage follows the ui-react ladder from context/roadmap.md (E2/E6).
Use this checklist to keep docs work aligned with component rollout. ui-react
currently ships 24 component modules (plus the cn class-merge helper),
exported from packages/ui-react/src/index.ts:
- Buttons & actions:
Button,ButtonIcon,ButtonMenu,Link - Form inputs:
Input,InputText,InputTextArea,InputSearch,InputSelect,InputDatePicker,Select(alias ofInputSelect),Checkbox,Radio(+RadioGroup),Switch - Search:
Search,SearchGlobal - Display & feedback:
Avatar,Tag,Tooltip,Breadcrumb - Layout & navigation:
Resizable,SidebarPrimary,SidebarSecondary,CardFilter - Not yet shipped: overlay primitives (
Dialog,Popover,Sheet), data display (Card,Table,DataTable,Chart), and the remaining composites/layout families tracked incontext/roadmap.md.
When a component is shipped in ui-react, update this ladder section and the
corresponding page in /docs/components/* in the same PR.
1) Switch package + styles
pnpm remove @acronis-platform/shadcn-uikit
pnpm add @acronis-platform/ui-react// before
import '@acronis-platform/shadcn-uikit/styles';
// after
import '@acronis-platform/ui-react/styles';2) Update imports
Legacy code usually imports components from @acronis-platform/shadcn-uikit/react.
Move migrated components to @acronis-platform/ui-react.
// before
import { Button, Input, Switch } from '@acronis-platform/shadcn-uikit/react';
// after
import { Button, Input, Switch } from '@acronis-platform/ui-react';3) Component mapping
The mapping below is based on current package exports.
Directly available in both packages
These keep the same name — only the import source changes.
Legacy (shadcn-uikit/react) | ui-react |
|---|---|
Avatar | Avatar |
Breadcrumb | Breadcrumb |
Button | Button |
Checkbox | Checkbox |
Link | Link |
Resizable | Resizable |
Select | Select |
Switch | Switch |
Tag | Tag |
Tooltip | Tooltip |
Renamed / split equivalents
ui-react standardizes form fields under an Input* namespace and splits the
legacy sidebar into two components. Map these by name:
| Legacy | ui-react equivalent |
|---|---|
Input | InputText |
Textarea | InputTextArea |
DatePicker | InputDatePicker |
RadioGroup | RadioGroup (from radio) |
RadioGroupItem | Radio |
ButtonGroup | ButtonMenu |
Sidebar | SidebarPrimary / SidebarSecondary |
The bare
Inputexport still exists inui-react, but new code should prefer the explicitInputTextfield.ui-reactalso adds form fields with no direct legacy equivalent:InputSearch,InputSelect,Search,SearchGlobal,ButtonIcon, andCardFilter.
Not yet available in ui-react (keep legacy for now)
Accordion, Alert, AlertDialog, AppShell, AspectRatio, AuthLayout, Badge, Calendar, Card, Carousel, Chart, Chip, Collapsible, Combobox, Command, DashboardLayout, DataTable, Dialog, Drawer, DropdownMenu, Field, Filter, Form, Grid, Label, NavigationMenu, NumberField, PageContent, PageHeader, Pagination, Popover, Progress, ScrollArea, SecondaryMenu, Section, Separator, Sheet, Skeleton, Slider, Sonner, Spinner, SplitLayout, Stack, Table, Tabs, ToggleGroup, Tree, VisuallyHidden, Widget, WidgetAlert, WidgetPlaceholder, WidgetProgressChunks, WidgetProgressTiers, WidgetProtectionStatus, WidgetProtectionSummary, WidgetTableData, WidgetText.
4) Codemods (where viable)
Codemod A — import source rewrite
Create ./codemods/shadcn-to-ui-react-imports.cjs:
module.exports = function transformer(file, api) {
const j = api.jscodeshift;
const root = j(file.source);
const fromLegacy = new Set([
'@acronis-platform/shadcn-uikit/react',
'@acronis-platform/shadcn-uikit',
]);
root.find(j.ImportDeclaration).forEach((path) => {
if (!fromLegacy.has(path.node.source.value)) return;
path.node.source = j.stringLiteral('@acronis-platform/ui-react');
});
return root.toSource({ quote: 'single' });
};Run it:
npx jscodeshift -t ./codemods/shadcn-to-ui-react-imports.cjs "src/**/*.{ts,tsx}" --parser=tsxCodemod B — radio rename
Legacy RadioGroupItem maps to Radio in ui-react.
Create ./codemods/radio-group-item-to-radio.cjs:
module.exports = function transformer(file, api) {
const j = api.jscodeshift;
const root = j(file.source);
root
.find(j.ImportDeclaration, {
source: { value: '@acronis-platform/ui-react' },
})
.forEach((path) => {
path.node.specifiers?.forEach((specifier) => {
if (
specifier.type === 'ImportSpecifier' &&
specifier.imported.name === 'RadioGroupItem'
) {
specifier.imported.name = 'Radio';
if (!specifier.local) specifier.local = j.identifier('Radio');
}
});
});
return root.toSource({ quote: 'single' });
};Run it:
npx jscodeshift -t ./codemods/radio-group-item-to-radio.cjs "src/**/*.{ts,tsx}" --parser=tsx⚠️ Keep mixed files on legacy imports if they still use legacy-only components or utilities/icons.
5) Manual follow-up checklist
- Keep legacy package only for components not yet in ui-react.
- Split mixed imports when needed:
import { Button, Input } from '@acronis-platform/ui-react';
import { Dialog, Popover } from '@acronis-platform/shadcn-uikit/react';- Re-test interactive components after migration (
Select,RadioGroup, sidebars). - Verify style import points to
@acronis-platform/ui-react/styles.
6) Migrating icons
Icons migrate independently of components. Legacy
@acronis-platform/shadcn-uikit re-exports icons under Acronis names
(EditIcon, CustomerIcon, SearchIcon); @acronis-platform/icons-react uses
descriptive names on a different art grid (PencilIcon, BriefcaseIcon,
MagnifierIcon), so names must be resolved authoritatively — not guessed.
The authoritative name map
icons-react ships the bridge as data — the
@acronis-platform/icons-react/legacy-map export (legacy-icon-map.json),
generated from the design-assets legacyNames bridge. It maps every legacy icon
name to its icons-react name per pack variant, classifying each as:
- mapped — safe 1:1 (with the name per variant, e.g.
stroke-mono). - colored — exists only in a multicolor pack (baked-in status/brand
color). No monochrome equivalent: keep it on a
*-multipack, or map to a mono base (CircleTimesIcon,TriangleWarningIcon, …) with a color className. Never silently flatten status color. - unresolved — logos/illustrations genuinely absent from the icon packs.
Because the map ships with the package, no monorepo checkout is needed — any app
resolves names from its installed icons-react.
The migrate-icons skill
The repo ships a reusable, dependency-free skill at
.claude/skills/migrate-icons/. Copy that folder into your app's
.claude/skills/ (or run its scripts directly) to drive the migration off the
shipped map:
# 1) Resolve — inventory your shadcn-uikit icon imports + build the map
TARGET=stroke-mono node .claude/skills/migrate-icons/scripts/resolve-map.mjs
# writes .icon-migration/iconmap.json and prints the colored / unresolved triage
# 2) Triage — decide the colored / unresolved icons; add chosen entries to the map by hand
# 3) Apply — rewrite imports + JSX, dedupe collisions, hold the rest on legacy
MAP=.icon-migration/iconmap.json \
FROM=@acronis-platform/shadcn-uikit \
TO=@acronis-platform/icons-react/stroke-mono \
node .claude/skills/migrate-icons/scripts/apply-icons.mjs
# 4) Verify — types + tests, then confirm only intended holds remain
npx tsc -b --noEmit && grep -R "@acronis-platform/shadcn-uikit" srcIconProps supports size/className/style, so size={16} and color
overrides keep type-checking. Held and unresolved icons stay on the legacy
package until you decide on them — icon migration never blocks on them.
7) Verify migration progress
# remaining legacy imports
grep -R "@acronis-platform/shadcn-uikit" src
# ui-react usage
grep -R "@acronis-platform/ui-react" srcA practical rollout is per feature/module: migrate files that use mapped components first, then keep the rest on legacy until their ui-react equivalents are available.
Edit on GitHubDesign-to-code contributor workflow
How contributors use Figma design context and Code Connect when implementing or updating ui-react components.
Shadow DOM Integration
How to render @acronis-platform/ui-react inside a shadow-DOM micro-frontend with fully styled portaled components and zero host style leakage.