UI8Kit is built on modular architecture principles where each layer has a clear responsibility. The library combines the flexibility of utility-first approach with the convenience of ready-made components.
- All visual properties available as component props
- Semantic prop names (
bg,c,p,m) - Consistent value system throughout the library
- Components can render as any HTML element via
componentprop - Full typing for all possible elements
- Flexibility in semantic markup
- Class Variance Authority for type-safe variants
- Variant composition without conflicts
- Automatic class merging through
tailwind-merge
- Full typing of all props
- IDE autocompletion
- Strict type safety
packages/@ui8kit/
├── core/ # Main library
│ ├── src/
│ │ ├── components/ # React components
│ │ │ ├── ui/ # Base UI components
│ │ │ └── *.tsx # Composite components
│ │ ├── variants/ # Variants system (CVA)
│ │ ├── lib/ # Utilities
│ │ └── index.ts # Main export
│ ├── package.json
│ └── tsconfig.json
├── docs/ # Documentation
└── create-app/ # CLI tool
import { cva } from 'class-variance-authority'
const buttonVariants = cva(
"inline-flex items-center justify-center", // base styles
{
variants: {
variant: {
primary: "bg-primary text-primary-foreground",
secondary: "bg-secondary text-secondary-foreground"
},
size: {
sm: "h-9 px-3",
lg: "h-11 px-8"
}
}
}
)interface BlockProps extends React.HTMLAttributes<HTMLElement> {
component?: ElementType
}
// Usage
<Block component="section" py="lg">Content</Block>
<Block component="form" onSubmit={handleSubmit}>Form</Block>import { twMerge } from 'tailwind-merge'
// Automatic class conflict resolution
twMerge('px-2 py-1', 'px-4') // → 'py-1 px-4'Defines all possible visual variants:
- spacing.ts - margin, padding, gaps
- colors.ts - background, text, border colors
- layout.ts - width, height, position, display
- typography.ts - font size, weight, alignment
- button.ts - button-specific variants
Base components without styles:
// Just forwardRef without classes
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
({ children, ...props }, ref) => (
<button ref={ref} {...props}>
{children}
</button>
)
)Applies variants to primitives:
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
({ variant = 'default', size = 'default', className, ...props }, ref) => (
<button
ref={ref}
className={cn(
buttonVariants({ variant, size }),
className
)}
{...props}
/>
)
)Composite components from base ones:
export function Card({ children, ...props }: CardProps) {
return (
<Block bg="card" rounded="lg" shadow="md" {...props}>
{children}
</Block>
)
}interface Theme {
name: string
rounded: Record<string, any> & { default: any }
buttonSize: Record<string, any> & { default: any }
isNavFixed?: boolean
}The library uses CSS variables for colors:
:root {
--primary: 221.2 83.2% 53.3%;
--background: 0 0% 100%;
}Props → Variants → Classes → Tailwind → CSS
↓
Component → forwardRef → Element → DOM
- Tree Shaking - Only used components end up in the bundle
- Runtime-free CSS-in-JS - All styles compiled to CSS
- Minimal re-renders - Stable references through useMemo
- Small bundle size - Dependencies: clsx, tailwind-merge, cva
// variants/new-feature.ts
export const newFeatureVariants = cva("", {
variants: {
variant: {
primary: "bg-primary",
secondary: "bg-secondary"
}
}
})// components/ui/NewComponent.tsx
export const NewComponent = forwardRef<Element, NewComponentProps>(
({ className, ...props }, ref) => (
<Box
ref={ref}
className={cn(newFeatureVariants({ variant }), className)}
{...props}
/>
)
)