Skip to main content
This guide describes the integration of @conty/design-system into the conty-web project, which uses Next.js 16, React 19, and TypeScript 5.

Prerequisites

The conty-web stack:
  • Framework: Next.js 16 with App Router
  • React: Version 19
  • TypeScript: Version 5
  • Current UI Stack: Tailwind 4 + shadcn/ui + Radix UI

Installation

1

Install the package

In the conty-web repository root:
npm install @conty/design-system
2

Import global styles

Add the design system styles to your root layout file:
app/layout.tsx
import "@conty/design-system/styles.css"
import type { Metadata } from "next"

export const metadata: Metadata = {
  title: "Conty",
  description: "Conty Web Application",
}

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body>{children}</body>
    </html>
  )
}
Import @conty/design-system/styles.css before any other custom styles to ensure proper CSS cascade.
3

Use components

Import components from the design system:
import { Button } from "@conty/design-system"

export function Example() {
  return <Button>Salvar</Button>
}

Component Usage Examples

Button

The Button component replaces the existing button from src/components/ui/button.tsx.
import { Button } from "@conty/design-system"

export function SaveButton() {
  return (
    <Button onClick={() => console.log('saved')}>
      Salvar
    </Button>
  )
}
Supported variants (Wave 1): default, secondary, destructive, outline, ghost, link Supported sizes: default, sm, lg, icon, icon-sm, icon-lg

Badge

The Badge component replaces src/components/ui/badge.tsx.
import { Badge } from "@conty/design-system"

export function StatusBadge() {
  return <Badge>Active</Badge>
}
Supported variants (Wave 1): default, secondary, destructive, outline
The warning variant from the legacy conty-web badge was intentionally excluded from Wave 1 to avoid hardcoded visual values outside the token contract.

Card

The Card component system replaces src/components/ui/card.tsx with a composition API.
import {
  Card,
  CardHeader,
  CardTitle,
  CardDescription,
  CardContent,
  CardFooter,
} from "@conty/design-system"

export function ProfileCard() {
  return (
    <Card>
      <CardHeader>
        <CardTitle>User Profile</CardTitle>
        <CardDescription>
          Manage your account settings and preferences
        </CardDescription>
      </CardHeader>
      <CardContent>
        <p>Your profile content goes here.</p>
      </CardContent>
      <CardFooter>
        <Button>Save Changes</Button>
      </CardFooter>
    </Card>
  )
}
Available components: Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter The composition API is preserved from the legacy implementation for seamless incremental migration.

Incremental Adoption Strategy

Do not attempt a “big bang” migration. Use the incremental approach below to minimize regression risk.
1

Start with low-risk components

Begin migration with foundational, low-risk components:
  • Button
  • Badge
  • Card
These components have:
  • High usage across the application
  • Simple, stable APIs
  • Low risk of regression
2

Validate visual semantics

Compare the visual output between the legacy conty-web components and the design system equivalents:
  1. Open the component in Storybook at http://localhost:6006
  2. Compare with the same component in your local conty-web development environment
  3. Verify spacing, colors, borders, and interactive states match expectations
  4. Test dark mode rendering
  • Default state matches legacy component
  • Hover states are consistent
  • Focus states show proper ring indicators
  • Disabled states have correct opacity
  • Dark mode colors are appropriate
  • Component responds to container sizing
  • Icons scale correctly
3

Migrate by module

Apply the design system components module by module rather than globally:
// Before (legacy)
import { Button } from "@/components/ui/button"

// After (design system)
import { Button } from "@conty/design-system"
Recommended migration order by module:
  1. Authentication/onboarding flows
  2. Dashboard and main feed
  3. Settings pages
  4. Billing and payments
  5. Advanced features and admin areas
This approach allows you to:
  • Validate each module independently
  • Rollback easily if issues arise
  • Maintain both legacy and new components during transition
4

Use feature flags for sensitive flows

For critical business flows, implement feature flags:
import { Button as DSButton } from "@conty/design-system"
import { Button as LegacyButton } from "@/components/ui/button"
import { useFeatureFlag } from "@/lib/feature-flags"

export function CheckoutButton() {
  const useDesignSystem = useFeatureFlag('design-system-checkout')
  const Button = useDesignSystem ? DSButton : LegacyButton

  return <Button>Complete Purchase</Button>
}

Wave 1 Component Migration Baseline

The initial migration wave focuses on three foundational components.

Migration Mapping

Legacy ComponentDesign SystemVariants Supported
src/components/ui/button.tsxButton from @conty/design-systemdefault, secondary, destructive, outline, ghost, link
src/components/ui/badge.tsxBadge from @conty/design-systemdefault, secondary, destructive, outline
src/components/ui/card.tsxCard, CardHeader, CardTitle, CardDescription, CardContent, CardFooter from @conty/design-systemComposition API preserved

Code Migration Examples

// Before
import { Button } from "@/components/ui/button"

export function SaveForm() {
  return (
    <Button variant="default" size="lg">
      Save Changes
    </Button>
  )
}

// After
import { Button } from "@conty/design-system"

export function SaveForm() {
  return (
    <Button variant="default" size="lg">
      Save Changes
    </Button>
  )
}
In most cases, migration is a simple import path change with no API modifications required.

Design Tokens Used in Wave 1

All Wave 1 components consume semantic tokens from @conty/tokens/tokens.json.

Token Categories Applied

  • Surface colors: color.surface.default, color.surface.elevated, color.surface.muted
  • Text colors: color.text.default, color.text.muted, color.text.onBrand
  • Brand colors: color.brand.primary
  • Border colors: color.border.default, color.border.focus
  • Status colors: color.status.destructive, color.status.onDestructive
  • Spacing: space.1 through space.8
  • Radius: radius.sm, radius.md, radius.lg
  • Typography: typography.fontFamily.sans, typography.text.sm, typography.text.base, typography.text.lg

Token Runtime Layer

Tokens are compiled to CSS custom properties in theme.css, which serves as the runtime layer for the web:
:root {
  --background: oklch(1 0 0);
  --foreground: oklch(0.2178 0 0);
  --primary: oklch(0.6248 0.2042 257.0818);
  /* ... */
}

.dark {
  --background: #0b0d10;
  --foreground: oklch(0.9551 0 0);
  /* ... */
}

Legacy Token Aliases

The @conty/tokens package maintains backward-compatible aliases in index.ts for gradual transition:
  • colors (legacy) → semantic color tokens
  • spacing (legacy) → space.* tokens
  • radii (legacy) → radius.* tokens
  • typography (legacy) → typography.* tokens
This allows existing code to continue working while you migrate to semantic token names.

Testing Integration

1

Visual testing

Compare components side-by-side in Storybook and your local development environment.
2

Accessibility validation

Run automated accessibility checks:
npm run test:a11y
Ensure no critical violations are introduced.
3

Component tests

If you have existing component tests, update imports:
// Update test imports
import { Button } from "@conty/design-system"
Verify all existing tests still pass.

Troubleshooting

Cause: CSS import order is incorrect.Solution: Ensure @conty/design-system/styles.css is imported before your custom styles:
import "@conty/design-system/styles.css"
import "./globals.css" // Your styles
Cause: The dark class is not being applied to the HTML element.Solution: Verify your theme provider is configured correctly:
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
  {children}
</ThemeProvider>
Cause: Peer dependencies may not be installed.Solution: Ensure React 19 is installed:
npm install react@^19.0.0 react-dom@^19.0.0
Cause: Missing CSS or token variables.Solution: Verify the import chain:
  1. Check that @conty/design-system/styles.css is imported
  2. Inspect the DOM to ensure CSS custom properties are defined
  3. Clear your build cache: rm -rf .next && npm run dev

Next Steps

Migration Strategy

Learn the full incremental migration approach

Components Reference

Explore all available components and APIs

Design Tokens

Deep dive into the token system

Storybook

View components in Storybook

Build docs developers (and LLMs) love