
Company News
Socket Joins New OpenJS Program to Fund Node.js Security Work
Socket is joining the OpenJS Security Stewardship Program to fund Node.js vulnerability research, maintainer remediation, and security releases.
@tekton-ui/ui
Advanced tools
Tekton UI Reference Component Library - High-quality, accessible React components with CSS Variables theming.
@tekton/ui provides 20 production-ready components + 13 screen templates built with:
pnpm add @tekton/ui
# or
npm install @tekton/ui
# or
yarn add @tekton/ui
import { Button, Input, Card } from '@tekton/ui';
import '@tekton/ui/styles';
export default function App() {
return (
<Card>
<CardHeader>
<CardTitle>Welcome to Tekton UI</CardTitle>
<CardDescription>Build accessible UIs faster</CardDescription>
</CardHeader>
<CardContent>
<Input placeholder="Enter your email..." />
</CardContent>
<CardFooter>
<Button variant="primary">Get Started</Button>
</CardFooter>
</Card>
);
}
Import the CSS Variables template and customize:
@import '@tekton/ui/styles';
:root {
/* Button Tokens */
--button-primary-background: #3b82f6;
--button-primary-foreground: white;
/* Input Tokens */
--input-border: #d1d5db;
--input-background: white;
/* Card Tokens */
--card-background: white;
--card-border: #e5e7eb;
/* ... customize 100+ other tokens */
}
Core UI building blocks with single responsibility:
Complex components built from primitives:
import { Button } from '@tekton/ui';
// Variants
<Button variant="default">Default</Button>
<Button variant="primary">Primary</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="destructive">Delete</Button>
<Button variant="outline">Outline</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="link">Link</Button>
// Sizes
<Button size="sm">Small</Button>
<Button size="md">Medium</Button>
<Button size="lg">Large</Button>
// States
<Button loading>Loading...</Button>
<Button disabled>Disabled</Button>
Props:
variant: "default" | "primary" | "secondary" | "destructive" | "outline" | "ghost" | "link"size: "sm" | "md" | "lg"loading: boolean<button> propsimport { Input } from '@tekton/ui';
// Basic usage
<Input type="text" placeholder="Enter text..." />
<Input type="email" placeholder="Email address" />
<Input type="password" placeholder="Password" />
// With error state
<Input type="text" aria-invalid="true" />
// Disabled
<Input disabled placeholder="Disabled input" />
Props:
type: "text" | "email" | "password" | "number" | "search" | "tel" | "url"<input> propsimport { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from '@tekton/ui';
<Card>
<CardHeader>
<CardTitle>Card Title</CardTitle>
<CardDescription>Card description or subtitle</CardDescription>
</CardHeader>
<CardContent>
<p>Main content goes here</p>
</CardContent>
<CardFooter>
<Button>Action</Button>
</CardFooter>
</Card>;
import { Form, FormField, FormLabel, FormControl, FormDescription, FormMessage } from '@tekton/ui';
import { Input } from '@tekton/ui';
<Form
onSubmit={e => {
e.preventDefault(); /* handle submit */
}}
>
<FormField name="email">
<FormLabel htmlFor="email">Email</FormLabel>
<FormControl>
<Input id="email" type="email" />
</FormControl>
<FormDescription>We'll never share your email.</FormDescription>
<FormMessage name="email">Invalid email address</FormMessage>
</FormField>
</Form>;
import {
Modal,
ModalTrigger,
ModalContent,
ModalHeader,
ModalTitle,
ModalDescription,
ModalFooter,
ModalClose,
} from '@tekton/ui';
import { Button } from '@tekton/ui';
<Modal>
<ModalTrigger asChild>
<Button>Open Modal</Button>
</ModalTrigger>
<ModalContent>
<ModalHeader>
<ModalTitle>Modal Title</ModalTitle>
<ModalDescription>Modal description text</ModalDescription>
</ModalHeader>
<div>Modal body content</div>
<ModalFooter>
<ModalClose asChild>
<Button variant="outline">Cancel</Button>
</ModalClose>
<Button variant="primary">Confirm</Button>
</ModalFooter>
</ModalContent>
</Modal>;
import {
Dropdown,
DropdownTrigger,
DropdownContent,
DropdownItem,
DropdownSeparator,
} from '@tekton/ui';
import { Button } from '@tekton/ui';
<Dropdown>
<DropdownTrigger asChild>
<Button>Open Menu</Button>
</DropdownTrigger>
<DropdownContent>
<DropdownItem onClick={() => console.log('Edit')}>Edit</DropdownItem>
<DropdownItem onClick={() => console.log('Duplicate')}>Duplicate</DropdownItem>
<DropdownSeparator />
<DropdownItem disabled>Disabled Item</DropdownItem>
<DropdownItem onClick={() => console.log('Delete')}>Delete</DropdownItem>
</DropdownContent>
</Dropdown>;
import { Tabs, TabsList, TabsTrigger, TabsContent } from '@tekton/ui';
<Tabs defaultValue="tab1">
<TabsList>
<TabsTrigger value="tab1">Tab 1</TabsTrigger>
<TabsTrigger value="tab2">Tab 2</TabsTrigger>
<TabsTrigger value="tab3">Tab 3</TabsTrigger>
</TabsList>
<TabsContent value="tab1">
<p>Content for Tab 1</p>
</TabsContent>
<TabsContent value="tab2">
<p>Content for Tab 2</p>
</TabsContent>
<TabsContent value="tab3">
<p>Content for Tab 3</p>
</TabsContent>
</Tabs>;
import { Checkbox } from '@tekton/ui';
// Basic checkbox
<label>
<Checkbox id="terms" />
Accept terms and conditions
</label>
// Indeterminate state
<Checkbox checked="indeterminate" />
// Disabled
<Checkbox disabled />
Props:
checked: boolean | "indeterminate"onCheckedChange: (checked: boolean | "indeterminate") => voidimport { RadioGroup, RadioGroupItem } from '@tekton/ui';
<RadioGroup defaultValue="option1">
<div>
<RadioGroupItem value="option1" id="opt1" />
<label htmlFor="opt1">Option 1</label>
</div>
<div>
<RadioGroupItem value="option2" id="opt2" />
<label htmlFor="opt2">Option 2</label>
</div>
<div>
<RadioGroupItem value="option3" id="opt3" />
<label htmlFor="opt3">Option 3</label>
</div>
</RadioGroup>;
import { Switch } from '@tekton/ui';
<label>
<Switch id="notifications" />
Enable notifications
</label>
<Switch checked onCheckedChange={(checked) => console.log(checked)} />
Props:
checked: booleanonCheckedChange: (checked: boolean) => voidimport { Slider } from '@tekton/ui';
// Basic slider
<label htmlFor="volume" id="volume-label">Volume</label>
<Slider
id="volume"
defaultValue={[50]}
min={0}
max={100}
step={1}
aria-labelledby="volume-label"
/>
// Range slider
<Slider defaultValue={[25, 75]} min={0} max={100} />
Props:
defaultValue: number[]min: numbermax: numberstep: numberimport { Progress } from '@tekton/ui';
<Progress value={50} aria-label="Upload progress" />
<Progress value={75} aria-label="Loading" />
<Progress value={100} aria-label="Complete" />
Props:
value: number (0-100)import { Avatar, AvatarImage, AvatarFallback } from '@tekton/ui';
<Avatar>
<AvatarImage src="https://example.com/avatar.jpg" alt="John Doe" />
<AvatarFallback>JD</AvatarFallback>
</Avatar>;
import { Badge } from '@tekton/ui';
<Badge variant="default">Default</Badge>
<Badge variant="primary">Primary</Badge>
<Badge variant="secondary">Secondary</Badge>
<Badge variant="destructive">Error</Badge>
<Badge variant="outline">Outline</Badge>
Props:
variant: "default" | "primary" | "secondary" | "destructive" | "outline"import { Text } from '@tekton/ui';
// Sizes
<Text size="xs">Extra small text</Text>
<Text size="sm">Small text</Text>
<Text size="md">Medium text</Text>
<Text size="lg">Large text</Text>
// Polymorphic rendering
<Text as="p">Paragraph</Text>
<Text as="span">Inline text</Text>
<Text as="div">Block text</Text>
Props:
as: "p" | "span" | "div" | "label"size: "xs" | "sm" | "md" | "lg"variant: "default" | "muted"import { Heading } from '@tekton/ui';
<Heading level={1}>Heading 1</Heading>
<Heading level={2}>Heading 2</Heading>
<Heading level={3}>Heading 3</Heading>
<Heading level={4}>Heading 4</Heading>
<Heading level={5}>Heading 5</Heading>
<Heading level={6}>Heading 6</Heading>
// Sizes
<Heading level={1} size="sm">Small H1</Heading>
<Heading level={2} size="lg">Large H2</Heading>
Props:
level: 1 | 2 | 3 | 4 | 5 | 6size: "sm" | "md" | "lg"import { Link } from '@tekton/ui';
<Link href="/home" variant="default">Default Link</Link>
<Link href="/about" variant="muted">Muted Link</Link>
<Link href="/contact" variant="underline">Underlined Link</Link>
Props:
href: stringvariant: "default" | "muted" | "underline"<a> propsimport { List, ListItem } from '@tekton/ui';
// Unordered list
<List as="ul">
<ListItem>Item 1</ListItem>
<ListItem>Item 2</ListItem>
<ListItem>Item 3</ListItem>
</List>
// Ordered list
<List as="ol">
<ListItem>First item</ListItem>
<ListItem>Second item</ListItem>
<ListItem>Third item</ListItem>
</List>
Props:
as: "ul" | "ol"import { Image } from '@tekton/ui';
<Image
src="https://example.com/image.jpg"
alt="Description of image"
/>
<Image
src="https://example.com/image.jpg"
alt="Cover image"
className="object-cover w-full h-64"
/>
Props:
src: stringalt: string (required for accessibility)<img> propsimport {
Table,
TableHeader,
TableBody,
TableFooter,
TableRow,
TableHead,
TableCell,
TableCaption,
} from '@tekton/ui';
<Table>
<TableCaption>List of users</TableCaption>
<TableHeader>
<TableRow>
<TableHead>Name</TableHead>
<TableHead>Email</TableHead>
<TableHead>Role</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell>John Doe</TableCell>
<TableCell>john@example.com</TableCell>
<TableCell>Admin</TableCell>
</TableRow>
<TableRow>
<TableCell>Jane Smith</TableCell>
<TableCell>jane@example.com</TableCell>
<TableCell>User</TableCell>
</TableRow>
</TableBody>
<TableFooter>
<TableRow>
<TableCell colSpan={3}>Total: 2 users</TableCell>
</TableRow>
</TableFooter>
</Table>;
All themeable properties use CSS Variables:
<Button variant="primary">
{/* Uses --button-primary-background and --button-primary-foreground */}
</Button>
Powered by class-variance-authority:
<Button variant="secondary" size="lg" loading>
Click me
</Button>
Works out of the box with sensible defaults:
import { Button } from '@tekton/ui';
<Button>Just works</Button>;
New in Phase 3: 13 Screen Templates for rapid full-screen composition.
Screen Templates provide pre-built, theme-aware full-screen layouts that combine multiple components into cohesive user experiences. Each template is registered in a centralized TemplateRegistry for easy discovery and reuse.
Features:
import { templateRegistry } from '@tekton/ui/templates';
// Get all templates
const allTemplates = templateRegistry.getAll(); // 13 templates
// Get by category
const authTemplates = templateRegistry.getByCategory('auth'); // 4 templates
// Get specific template
const loginTemplate = templateRegistry.get('auth.login');
import {
LoginTemplate,
SignupTemplate,
ForgotPasswordTemplate,
VerificationTemplate,
} from '@tekton/ui/templates/auth';
auth.login) - Centered login card with email/passwordauth.signup) - Registration form with terms acceptanceauth.forgot-password) - Password reset flowauth.verification) - Email verification confirmationimport { LandingTemplate, PreferencesTemplate, ProfileTemplate } from '@tekton/ui/templates/core';
home.landing) - Full-width landing page with CTAsettings.preferences) - Sidebar settings layoutaccount.profile) - User profile with avatar editingimport {
LoadingTemplate,
ErrorTemplate,
EmptyTemplate,
ConfirmationTemplate,
SuccessTemplate,
} from '@tekton/ui/templates/feedback';
feedback.loading) - Loading skeleton statefeedback.error) - Error state with retry buttonfeedback.empty) - Empty state with CTAfeedback.confirmation) - Dialog confirmationfeedback.success) - Success message with next stepsimport { DashboardTemplate } from '@tekton/ui/templates/dashboard';
dashboard.overview) - Dashboard layout with sidebarScreenTemplate interfaceslots, texts, options)The TemplateRegistry provides centralized template management:
import { templateRegistry } from '@tekton/ui/templates/registry';
// Get all templates
const allTemplates = templateRegistry.getAll(); // 13 templates
// Get templates by category
const authTemplates = templateRegistry.getByCategory('auth'); // 4 templates
// Get specific template
const loginTemplate = templateRegistry.get('auth.login');
// Find by required components
const formsTemplates = templateRegistry.findByRequiredComponents(['Button', 'Input', 'Form']);
Design Reference: All templates follow Claude.ai Design Philosophy - clarity, accessibility, universality.
Completed (2026-02-01):
ScreenTemplate, TemplateRegistry)Next Steps:
@tekton/ui uses a 3-layer CSS Variables architecture:
--color-primary: #3b82f6;
--color-destructive: #ef4444;
--spacing-sm: 0.5rem;
--radius-md: 0.375rem;
--text-primary: var(--color-primary);
--bg-destructive: var(--color-destructive);
Button Tokens:
--button-default-background
--button-default-foreground
--button-primary-background
--button-primary-foreground
--button-secondary-background
--button-secondary-foreground
--button-destructive-background
--button-destructive-foreground
--button-outline-border
--button-outline-foreground
--button-ghost-hover-background
--button-link-foreground
--button-disabled-opacity
--button-focus-ring
Input Tokens:
--input-background
--input-foreground
--input-border
--input-placeholder
--input-focus-ring
--input-disabled-background
--input-disabled-foreground
Card Tokens:
--card-background
--card-foreground
--card-border
Modal Tokens:
--modal-background
--modal-border
--modal-overlay-background
--modal-title-foreground
--modal-description-foreground
Form Tokens:
--form-label-foreground
--form-message-destructive
--form-description-foreground
Other Component Tokens:
--badge-*-background, --badge-*-foreground, --badge-*-border--dropdown-*-background, --dropdown-item-*--tabs-*-background, --tabs-trigger-*--table-*-background, --table-border--progress-background, --progress-indicator-background--slider-track-background, --slider-thumb-*--avatar-background, --avatar-foreground/* dark-theme.css */
@import '@tekton/ui/styles';
:root {
/* Atomic Layer */
--color-primary: #60a5fa;
--color-background: #1f2937;
--color-foreground: #f9fafb;
/* Button Layer */
--button-primary-background: var(--color-primary);
--button-primary-foreground: #000000;
--button-default-background: #374151;
--button-default-foreground: var(--color-foreground);
/* Input Layer */
--input-background: #374151;
--input-foreground: var(--color-foreground);
--input-border: #4b5563;
/* Card Layer */
--card-background: #374151;
--card-foreground: var(--color-foreground);
--card-border: #4b5563;
}
# Clone repository
git clone https://github.com/your-org/tekton.git
cd tekton/packages/ui
# Install dependencies (requires pnpm)
pnpm install
# Run tests
pnpm test
# Run tests with coverage (target: ≥90%)
pnpm test:coverage
# Run tests in watch mode
pnpm test:watch
# Type check (TypeScript 5.7+ strict mode)
pnpm type-check
# Lint (ESLint 9)
pnpm lint
# Build (outputs to dist/)
pnpm build
# Clean build artifacts
pnpm clean
packages/ui/
├── src/
│ ├── primitives/ # 14 primitive components
│ │ ├── button.tsx
│ │ ├── input.tsx
│ │ ├── checkbox.tsx
│ │ └── ...
│ ├── components/ # 6 composed components
│ │ ├── card.tsx
│ │ ├── form.tsx
│ │ ├── modal.tsx
│ │ └── ...
│ ├── lib/
│ │ └── utils.ts # cn() utility
│ └── index.ts # Main export
├── __tests__/
│ ├── primitives/ # Primitive tests
│ ├── components/ # Component tests
│ ├── lib/ # Utility tests
│ └── accessibility.test.tsx # WCAG compliance
├── vitest.config.ts
├── tsconfig.json
└── package.json
All 20 components include comprehensive test coverage:
Unit Tests (Vitest + Testing Library)
Accessibility Tests (vitest-axe)
Keyboard Navigation Tests
User Interaction Tests (userEvent)
# All tests
pnpm test
# Specific file
pnpm vitest run __tests__/primitives/button.test.tsx
# Watch mode
pnpm test:watch
# Coverage report
pnpm test:coverage
Note: Internet Explorer is not supported.
All components are fully typed with TypeScript 5.7+:
import { Button, ButtonProps } from '@tekton/ui';
// Type-safe props
const MyButton: React.FC<ButtonProps> = props => {
return <Button {...props} />;
};
// Type inference
<Button
variant="primary" // ✓ Valid
variant="invalid" // ✗ TypeScript error
size="lg" // ✓ Valid
onClick={e => {
// e is typed as MouseEvent<HTMLButtonElement>
console.log(e.currentTarget);
}}
/>;
Contributions are welcome! Please read our contributing guidelines before submitting a PR.
git checkout -b feature/amazing-feature)pnpm test)pnpm type-check)pnpm lint)git commit -m 'Add amazing feature')git push origin feature/amazing-feature)any typesMIT License - see LICENSE for details
Built with:
Version: 1.0.0 Last Updated: 2026-01-26 Maintained by: Tekton Team
FAQs
Tekton UI Reference Component Library
The npm package @tekton-ui/ui receives a total of 5 weekly downloads. As such, @tekton-ui/ui popularity was classified as not popular.
We found that @tekton-ui/ui demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Company News
Socket is joining the OpenJS Security Stewardship Program to fund Node.js vulnerability research, maintainer remediation, and security releases.

Security News
Two compromised GitHub Actions were re-enabled with malicious tags intact, exposing thousands of downstream repositories to Mini Shai-Hulud.

Research
/Security News
A malicious Firefox extension fetches its payload after installation to evade detection, steal Google session cookies, and automate account takeover.