Migration

V2 to V3

Upgrade to the V3 npm runtime package for centralized semver updates, or move selected components to the source registry when you need local ownership. Both routes can coexist during an incremental migration.

V2 blocker fixes through 2027-03-31End of maintenance 2027-06-30

Npm package upgrade

Keep supported package imports and move the application to the V3 runtime package.

pnpm add poyraz-ui@3

Own the source

Follow the incremental sequence below for components that need source-level control.

pnpm dlx shadcn@latest add @poyraz/button

Incremental sequence

1. Foundation

Install the generated theme, utilities and shared recipes before visual components.

pnpm dlx shadcn@latest add @poyraz/poyraz-theme @poyraz/poyraz-utils @poyraz/poyraz-recipes

2. Primitives

Move Button, Input and Card separately and compare dimensions before changing variants.

pnpm dlx shadcn@latest add @poyraz/button @poyraz/input @poyraz/card

3. Interactive components

Move one Radix family at a time, then verify keyboard and focus behavior.

pnpm dlx shadcn@latest add @poyraz/dialog @poyraz/select @poyraz/dropdown-menu @poyraz/tabs

4. Organisms and blocks

Install composite layouts only after their child component migrations are stable.

pnpm dlx shadcn@latest add @poyraz/navbar @poyraz/sidebar @poyraz/footer @poyraz/dashboard-shell-block

Component mapping

This mapping is only required for the source-ownership route. Install the registry item first, then replace that component's package import with the local target.

LayerV2 symbolsV3 itemLocal import
Atomspoyraz-ui/atoms: Avatar*@poyraz/avatar@/components/ui/atoms/avatar
Atomspoyraz-ui/atoms: Badge@poyraz/badge@/components/ui/atoms/badge
Atomspoyraz-ui/atoms: Button, buttonVariants@poyraz/button@/components/ui/atoms/button
Atomspoyraz-ui/atoms: Card*@poyraz/card@/components/ui/atoms/card
Atomspoyraz-ui/atoms: BasicContentCard, GlassCard and card compositions@poyraz/card-variants@/components/ui/atoms/card-variants
Atomspoyraz-ui/atoms: Checkbox@poyraz/checkbox@/components/ui/atoms/checkbox
Atomspoyraz-ui/atoms: Input, InputGroup*@poyraz/input@/components/ui/atoms/input
Atomspoyraz-ui/atoms: NumberInput, MaskedInput and field helpers@poyraz/form-fields@/components/ui/atoms/form-fields
Atomspoyraz-ui/atoms: Label@poyraz/label@/components/ui/atoms/label
Atomspoyraz-ui/atoms: Logo@poyraz/logo@/components/ui/atoms/logo
Atomspoyraz-ui/atoms: RadioGroup*@poyraz/radio-group@/components/ui/atoms/radio-group
Atomspoyraz-ui/atoms: ScrollArea@poyraz/scroll-area@/components/ui/atoms/scroll-area
Atomspoyraz-ui/atoms: Separator@poyraz/separator@/components/ui/atoms/separator
Atomspoyraz-ui/atoms: Skeleton@poyraz/skeleton@/components/ui/atoms/skeleton
Atomspoyraz-ui/atoms: Switch@poyraz/switch@/components/ui/atoms/switch
Atomspoyraz-ui/atoms: Textarea@poyraz/textarea@/components/ui/atoms/textarea
Atomspoyraz-ui/atoms: Typography, TextEffect@poyraz/typography@/components/ui/atoms/typography
Atomspoyraz-ui/atoms: Pattern*@poyraz/bg-pattern@/components/ui/atoms/bg-pattern
Moleculespoyraz-ui/molecules: Accordion*@poyraz/accordion@/components/ui/molecules/accordion
Moleculespoyraz-ui/molecules: Alert*@poyraz/alert@/components/ui/molecules/alert
Moleculespoyraz-ui/molecules: Autocomplete@poyraz/autocomplete@/components/ui/molecules/autocomplete
Moleculespoyraz-ui/molecules: Breadcrumb*@poyraz/breadcrumb@/components/ui/molecules/breadcrumb
Moleculespoyraz-ui/molecules: Calendar@poyraz/calendar@/components/ui/molecules/calendar
Moleculespoyraz-ui/molecules: CommandPalette*@poyraz/command-palette@/components/ui/molecules/command-palette
Moleculespoyraz-ui/molecules: DatePicker@poyraz/date-picker@/components/ui/molecules/date-picker
Moleculespoyraz-ui/molecules: Dialog*@poyraz/dialog@/components/ui/molecules/dialog
Moleculespoyraz-ui/molecules: Drawer*@poyraz/drawer@/components/ui/molecules/drawer
Moleculespoyraz-ui/molecules: DropdownMenu*@poyraz/dropdown-menu@/components/ui/molecules/dropdown-menu
Moleculespoyraz-ui/molecules: Form*@poyraz/form@/components/ui/molecules/form
Moleculespoyraz-ui/molecules: HoverCard*@poyraz/hover-card@/components/ui/molecules/hover-card
Moleculespoyraz-ui/molecules: Mermaid@poyraz/mermaid@/components/ui/molecules/mermaid
Moleculespoyraz-ui/molecules: Modal*@poyraz/modal@/components/ui/molecules/modal
Moleculespoyraz-ui/molecules: Pagination*@poyraz/pagination@/components/ui/molecules/pagination
Moleculespoyraz-ui/molecules: Popover*@poyraz/popover@/components/ui/molecules/popover
Moleculespoyraz-ui/molecules: Select*@poyraz/select@/components/ui/molecules/select
Moleculespoyraz-ui/molecules: Sheet*@poyraz/sheet@/components/ui/molecules/sheet
Moleculespoyraz-ui/molecules: Tabs*@poyraz/tabs@/components/ui/molecules/tabs
Moleculespoyraz-ui/molecules: Toaster, toast@poyraz/sonner@/components/ui/molecules/sonner
Moleculespoyraz-ui/molecules: Tooltip*@poyraz/tooltip@/components/ui/molecules/tooltip
Blockspoyraz-ui/molecules: ArticleCard@poyraz/article-card@/components/ui/blocks/card-templates/article-card
Blockspoyraz-ui/molecules: ImageCard@poyraz/image-card@/components/ui/blocks/card-templates/image-card
Blockspoyraz-ui/molecules: NewsCard@poyraz/news-card@/components/ui/blocks/card-templates/news-card
Blockspoyraz-ui/molecules: StatsCard@poyraz/stats-card@/components/ui/blocks/card-templates/stats-card
Blockspoyraz-ui/molecules: TestimonialCard@poyraz/testimonial-card@/components/ui/blocks/card-templates/testimonial-card
Blockspoyraz-ui/molecules: PricingCard@poyraz/pricing-card@/components/ui/blocks/card-templates/pricing-card
Blockspoyraz-ui/molecules: ProductCard@poyraz/product-card@/components/ui/blocks/card-templates/product-card
Organismspoyraz-ui/organisms: AnnouncementBar@poyraz/announcement-bar@/components/ui/organisms/announcement-bar
Organismspoyraz-ui/organisms: DataTable*@poyraz/data-table@/components/ui/organisms/data-table
Organismspoyraz-ui/organisms: DataTableCore@poyraz/data-table-core@/components/ui/organisms/data-table-core
Organismspoyraz-ui/organisms: Footer*@poyraz/footer@/components/ui/organisms/footer
Organismspoyraz-ui/organisms: FooterNewsletter@poyraz/footer-newsletter@/components/ui/organisms/footer-newsletter
Organismspoyraz-ui/organisms: Navbar*@poyraz/navbar@/components/ui/organisms/navbar
Organismspoyraz-ui/organisms: Sidebar*@poyraz/sidebar@/components/ui/organisms/sidebar

Prop mapping

ComponentV2V3Action
AllclassNameclassNamePreserved; re-apply overrides after visual comparison.
All forwardRef componentsrefrefPreserved.
ButtonasChildasChildPreserved; disabled links now use aria-disabled.
ButtonloadingloadingPreserved; V3 keeps an accessible name and blocks interaction.
Buttonvariant, sizevariant, size, radius, effect, fillDirection, swapTargetExisting names compile; review changed dimensions and opt into new effects.
Cardvariantvariant, radiusLegacy variants remain; V3 default radius is xl.
Badgevariantvariant, size, radiusExisting variants remain; root element is now span rather than div.
Input/Textareanative propsnative props plus size/radius/invalidPreserved; use aria-invalid for validation state.
Dialog/Sheet/Modalopen, defaultOpen, onOpenChangesame controlled contractPreserved; re-test focus return and portal theme inheritance.
Select/Tabs/Accordionvalue, defaultValue, onValueChangesame controlled contractPreserved; re-test keyboard behavior.
Navbar/Sidebarlayout propscomposable parts plus container-responsive propsMigrate composition manually; codemod only changes safe imports.
ThemeThemeProvider themes objectCSS variables on :root/.dark/[data-poyraz-theme]Remove runtime theme objects after CSS parity is verified.

Variant changes

ComponentV2V3Action
Buttondefault|secondary|outline|destructive|ghost|linksame namesVisual treatment and control heights changed; snapshot each use.
Buttonsize=default (32px)size=sm (32px)Use sm to preserve approximate old height; V3 default is 40px.
Buttonsize=sm (28px)size=xs (28px)Use xs for approximate parity.
Buttonsize=lg (36px)size=default (40px) or lg (44px)No exact alias; choose by layout.
Carddefault|bordered|elevated|highlight|ghost|interactivesame namesCompatibility names remain but V3 removes directional hover movement.
Badgedefault|secondary|outline|destructivesame plus glass|info|success|warningExisting names remain; V3 defaults to full radius.
Typographylegacy visual variantssemantic typography variants and text effectsReview heading level separately from visual variant.

Token mapping

V2 tokenV3 tokenStatus
--poyraz-background--poyraz-backgroundpreserved
--poyraz-foreground--poyraz-foregroundpreserved
--poyraz-primary*--poyraz-primary*preserved, values redesigned
--poyraz-secondary*--poyraz-secondary*preserved, semantic surface
--poyraz-muted*--poyraz-muted*preserved
--poyraz-accent*--poyraz-accent*preserved
--poyraz-destructive*--poyraz-destructive*preserved
--poyraz-border / --poyraz-border-strongsame namespreserved
--poyraz-input--poyraz-inputpreserved
--poyraz-ring--poyraz-ringpreserved
--poyraz-overlay*--poyraz-overlay*preserved, backdrop policy added
--poyraz-surface-50/100/200same aliases; prefer --poyraz-surface, -subtle, -raised, -elevatedcompatibility alias
--poyraz-info/success/warning*same semantic namespreserved, independent status palettes
--font-sans--poyraz-font-primaryTailwind alias remains
--font-secondary--poyraz-font-secondaryTailwind alias remains
custom hardcoded glass colors--poyraz-glass-*replace
custom duration/easing literals--poyraz-motion-duration-* / --poyraz-motion-ease-*replace
custom border radius literals--poyraz-radius-*replace

Source route: remove V2 runtime theme objects

The registry theme owns variables. A provider-independent application only needs to set the selector consumed by the preset.

export function setColorTheme(theme: "light" | "dark") {
  document.documentElement.dataset.poyrazTheme = theme;
  localStorage.setItem("color-theme", theme);
}

Next.js with next-themes

"use client";

import { ThemeProvider } from "next-themes";

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <ThemeProvider attribute="data-poyraz-theme" defaultTheme="system" enableSystem>
      {children}
    </ThemeProvider>
  );
}

Add suppressHydrationWarning to the root html element and mount theme-dependent controls on the client.

Audit and safe codemod

pnpm migration:audit src app components
pnpm migration:tokens src app components
pnpm migration:codemod -- src app components
pnpm migration:codemod --write -- src app components

The codemod changes named imports only when the local registry target already exists. It does not rewrite props, compositions, namespace imports or consumer component files.

Overwrite and rollback policy

  1. Commit before each registry install and never enable global overwrite.
  2. Keep consumer customization in a separate commit from upstream source updates.
  3. Rollback the component-specific commit and restore its pinned V2 import.
  4. Remove registry dependencies only after checking migrated dependents.
  5. Re-run typecheck, production build, keyboard and visual checks.