Skip to main content

@stoneforge/ui

React 19 component library for building Stoneforge front-ends. Includes core UI primitives, domain-specific components, real-time communication hooks, and a full design token system.
React 19: Built with the latest React features including automatic batching, concurrent rendering, and Server Components support.

Installation

npm install @stoneforge/ui

Peer Dependencies

npm install react react-dom
npm install @tanstack/react-query @tanstack/react-router
Optional for rich text editing:
npm install @tiptap/react @tiptap/starter-kit @tiptap/extension-link
npm install lowlight marked turndown

Quick Start

import '@stoneforge/ui/styles/tokens.css';
import { Button, Card, CardHeader, CardTitle, CardContent } from '@stoneforge/ui';
import { useTheme } from '@stoneforge/ui/hooks';

function App() {
  const { isDark, toggleDarkMode } = useTheme();

  return (
    <Card>
      <CardHeader>
        <CardTitle>Welcome to Stoneforge</CardTitle>
      </CardHeader>
      <CardContent>
        <Button variant="primary" onClick={toggleDarkMode}>
          {isDark ? 'Light Mode' : 'Dark Mode'}
        </Button>
      </CardContent>
    </Card>
  );
}

Components

Core UI

import { Button } from '@stoneforge/ui';

<Button variant="primary" onClick={() => {}}>
  Primary
</Button>

<Button variant="secondary">Secondary</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="danger">Danger</Button>
<Button variant="outline">Outline</Button>

<Button size="sm">Small</Button>
<Button size="md">Medium</Button>
<Button size="lg">Large</Button>

<Button disabled>Disabled</Button>
<Button loading>Loading...</Button>

Layout

import { AppShell, Sidebar, Header } from '@stoneforge/ui/layout';

function App() {
  return (
    <AppShell>
      <Sidebar />
      <div className="main-content">
        <Header title="Dashboard" />
        <main>{children}</main>
      </div>
    </AppShell>
  );
}

Domain Components

import { TaskCard } from '@stoneforge/ui/domain';
import type { Task } from '@stoneforge/core';

<TaskCard
  task={task}
  onClick={() => navigate(`/tasks/${task.id}`)}
  onAssign={(taskId) => handleAssign(taskId)}
  showAssignees
  showPriority
  showDependencies
/>

Skeleton Loading

import { 
  Skeleton, 
  SkeletonText, 
  SkeletonAvatar,
  SkeletonCard 
} from '@stoneforge/ui';

<Skeleton className="h-10 w-full" />
<SkeletonText lines={3} />
<SkeletonAvatar size="lg" />
<SkeletonCard />

Hooks

Theme & Responsive

import { useTheme } from '@stoneforge/ui/hooks';

const { 
  isDark, 
  isHighContrast,
  theme,          // 'light' | 'dark' | 'system'
  toggleDarkMode,
  setTheme,
  setHighContrast 
} = useTheme();

<Button onClick={toggleDarkMode}>
  {isDark ? 'Light' : 'Dark'} Mode
</Button>

Real-time Communication

import { useWebSocket } from '@stoneforge/ui/hooks';

const { 
  connectionState,  // 'connecting' | 'connected' | 'disconnected'
  subscribe,
  unsubscribe,
  send,
  close
} = useWebSocket({
  url: 'ws://localhost:3456/ws',
  channels: ['tasks', 'agents'],
  reconnect: true,
  reconnectInterval: 5000,
});

useEffect(() => {
  const unsubscribe = subscribe('tasks', (event) => {
    console.log('Task event:', event);
    // Invalidate queries, update state, etc.
  });
  return unsubscribe;
}, [subscribe]);

Keyboard Shortcuts

import { useKeyboardShortcut } from '@stoneforge/ui/hooks';

useKeyboardShortcut('cmd+k', () => {
  openCommandPalette();
});

useKeyboardShortcut('cmd+n', () => {
  createNewTask();
});

useKeyboardShortcut('esc', () => {
  closeModal();
});

API Clients

import { WebSocketClient } from '@stoneforge/ui/api';

const ws = new WebSocketClient({
  url: 'ws://localhost:3456/ws',
  reconnect: true,
  heartbeatInterval: 30000,
});

ws.subscribe('tasks', (event) => {
  console.log('Task event:', event);
});

ws.send({ type: 'subscribe', channels: ['agents'] });

ws.close();

Design Tokens

Import the CSS custom properties in your app entry point:
@import '@stoneforge/ui/styles/tokens.css';

Color System

:root {
  --color-background: #ffffff;
  --color-foreground: #0a0a0a;
  --color-primary: #2563eb;
  --color-secondary: #64748b;
  --color-success: #10b981;
  --color-warning: #f59e0b;
  --color-danger: #ef4444;
  --color-border: #e5e7eb;
}

Spacing & Typography

--spacing-0: 0;
--spacing-1: 0.25rem;  /* 4px */
--spacing-2: 0.5rem;   /* 8px */
--spacing-3: 0.75rem;  /* 12px */
--spacing-4: 1rem;     /* 16px */
--spacing-6: 1.5rem;   /* 24px */
--spacing-8: 2rem;     /* 32px */
--spacing-12: 3rem;    /* 48px */

Visualizations

import { LineChart } from '@stoneforge/ui/visualizations';

const data = [
  { date: '2026-01-01', value: 10 },
  { date: '2026-01-02', value: 15 },
  { date: '2026-01-03', value: 12 },
];

<LineChart
  data={data}
  xKey="date"
  yKey="value"
  title="Task Completion Rate"
/>

Entry Points

import { Button, Card, Dialog } from '@stoneforge/ui';
// All components, hooks, and utilities
React 19: This package uses React 19 features. Ensure your project is using React 19 or later.

Next Steps

Quarry API

Connect UI to the data layer

Smithy Orchestration

Build agent management interfaces

Build docs developers (and LLMs) love