Thanks for your interest in contributing! UIX is an AI-to-UI protocol layer, not a traditional component library.
The consumer is AI, not developers.
When contributing, remember:
- We're building a protocol that AI can generate (UIX IR)
- Components are renderers for UIX IR types
- The focus is on AI-generatable JSON, not developer ergonomics
| Package | Layer | Purpose |
|---|---|---|
@uix-ai/core |
Protocol | UIX IR JSON Schema & TypeScript types |
@uix-ai/react |
Renderer | React renderer & base components |
@uix-ai/stream |
Renderer | Streaming content (self-healing markdown) |
@uix-ai/agent |
Renderer | Conversation & block renderers |
@uix-ai/tokens |
Design System | Colors, typography, spacing |
This guide will help you add new components or improve existing ones.
When creating a new component, ensure it meets these criteria:
- Keyboard navigation support
- Screen reader compatible (ARIA labels)
- Focus management
- Proper semantic HTML
- Uses design tokens from
@uix-ai/tokens - Follows Lucid color philosophy (no AI purple)
- Consistent with existing component patterns
- Responsive by default
- TypeScript types fully defined
- Props documented with JSDoc comments
- Examples in component file
- Composable via
asChildwhen appropriate
- Clear inline documentation
- Usage examples in comments
- Design rationale explained
- Common patterns demonstrated
packages/react/src/components/[component-name]/
├── [component-name].tsx # Main component file
├── index.ts # Exports
└── README.md # Component-specific docs (optional)
Use this template when creating a new component:
/**
* [ComponentName] Component
*
* [Brief description of what this component does]
*
* ## AI Usage Guide
*
* ### Basic Usage
* ```tsx
* import { ComponentName } from '@uix-ai/react'
*
* <ComponentName>Content</ComponentName>
* ```
*
* ### Design Principles
* - [Principle 1]
* - [Principle 2]
*
* ### Variants
* - variant1: [description]
* - variant2: [description]
*/
import * as React from 'react'
import { cva, type VariantProps } from 'class-variance-authority'
import { cn } from '../../lib/utils'
const componentVariants = cva(
// Base styles
'base-class-here',
{
variants: {
variant: {
default: 'default-classes',
// Add more variants
},
size: {
sm: 'small-size-classes',
default: 'default-size-classes',
lg: 'large-size-classes',
},
},
defaultVariants: {
variant: 'default',
size: 'default',
},
}
)
export interface ComponentNameProps
extends React.HTMLAttributes<HTMLDivElement>, // or appropriate HTML element
VariantProps<typeof componentVariants> {
/**
* Prop description
*/
propName?: string
}
const ComponentName = React.forwardRef<HTMLDivElement, ComponentNameProps>(
({ className, variant, size, ...props }, ref) => {
return (
<div
className={cn(componentVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
)
}
)
ComponentName.displayName = 'ComponentName'
export { ComponentName, componentVariants }Always use design tokens, never hardcoded values:
className="bg-primary-500 text-white border-border"className="bg-[#0EA5E9] text-[#FFFFFF] border-[#E5E5E5]"Prefer semantic tokens when available:
className="bg-background text-foreground" // ✅
className="bg-white text-gray-900" // ⚠️ Less semantic- Build the package:
cd packages/react
pnpm build- Check TypeScript types:
pnpm tsc --noEmit- Test in Storybook (once configured):
pnpm storybookEvery component should have:
- Header comment explaining purpose
- AI Usage Guide section with:
- Basic usage examples
- Design principles
- Variant explanations
- JSDoc for all props
- Inline comments for complex logic
/**
* Render as a child element instead of a div.
* Useful for creating links that look like cards.
*
* @example
* <Card asChild>
* <a href="/somewhere">Card link</a>
* </Card>
*/
asChild?: boolean- Fork the repository
- Create a feature branch:
git checkout -b feat/add-card-component
- Make your changes
- Commit with clear message:
git commit -m "feat: add Card component with variants" - Push and create PR:
git push origin feat/add-card-component
type(scope): subject
[optional body]
Types:
feat: New featurefix: Bug fixdocs: Documentationstyle: Formattingrefactor: Code restructuringtest: Adding testschore: Maintenance
We're building in this order:
- UIX IR JSON Schema definition
- TypeScript type definitions
- Design tokens system
- React base components
- TextBlock → StreamMarkdown
- ToolBlock → ToolResult
- ThinkingBlock → ThinkingIndicator
- ImageBlock → Image renderer
- FileBlock → File renderer
- ReactRenderer (default)
- AgentX adapter
- A2UI adapter (when mature)
- MCP Apps adapter (when mature)
Prefer simple, composable components:
// ✅ Good
<Card>
<CardHeader>Title</CardHeader>
<CardContent>Content</CardContent>
</Card>
// ❌ Avoid
<Card title="Title" content="Content" />Use Radix primitives for complex interactions:
import * as Dialog from '@radix-ui/react-dialog'
// Build on top of Radix, add Lucid stylingKeep it simple:
- Don't add variants "just in case"
- Don't create abstractions for single use cases
- Prefer explicit over clever
Always design mobile-first with Tailwind:
// ✅ Mobile-first
className="text-sm md:text-base lg:text-lg"
// ❌ Desktop-first
className="text-lg md:text-base sm:text-sm"- Open an issue: https://github.com/Deepractice/UIX/issues
- Discussion: https://github.com/Deepractice/UIX/discussions
Made with ❤️ by Deepractice