Skip to content
Version: Current

@tcpsystems/ui: the shared UI library

Every web surface in the estate (console, studio, the ops harness console and this site’s islands) builds on @tcpsystems/ui (tcpsystems/ui, pinned in package.json at 78eedc4 as of 2026-11-03). It is 16 typed Svelte 5 components wrapping Bits UI v2 primitives in the suite tokens, plus cn(), variants.ts and the style layers.

Everything below is the real library rendering inside this page:

Variants
Badges
ok warn bad info accent plain

UiProvider (Tooltip context), Button, IconButton, Input, Select, Dialog, DropdownMenu, Tabs, Table (sortable and selectable, a native <table> with aria-sort), DataTable, Badge, Switch, Tooltip, Toast (svelte-sonner, toast re-exported), Card, Skeleton.

Bits UI v2 ships no input, table or skeleton primitive. Input is a native <input> with a real <label>, Table is a native <table>, and Skeleton is an aria-hidden div. Behaviour and ARIA from Bits UI are forwarded, never stripped. Variant classes resolve only to semantic tokens, which a test pins: no raw palette values.

// package.json: pinned git dependency, source distribution via the svelte export condition
"dependencies": {
"@tcpsystems/ui": "github:tcpsystems/ui#<commit-sha>"
}
<script>
import { UiProvider, Button, Badge } from '@tcpsystems/ui';
</script>
<UiProvider>
<Button variant="primary">Save</Button>
<Badge tone="ok" dot>live</Badge>
</UiProvider>
/* app entry CSS: after tailwindcss, with the library sources scanned */
@import 'tailwindcss';
@source '../node_modules/@tcpsystems/ui/src';
@import '@tcpsystems/ui/styles/base.css';

Three style layers ship separately, so a non-app surface such as this docs site can take tokens and primitives without the element reset:

  • @tcpsystems/ui/styles/base.css: tokens, primitives and base reset (apps: console, studio, ops console).
  • @tcpsystems/ui/styles/tokens.css: @theme wiring and the light-dark() palette only.
  • @tcpsystems/ui/styles/components.css: the .panel, .field, .input and .data-table primitives only.

The @source line matters. Tailwind v4 auto-detection skips node_modules, so without it the library’s utility classes silently do not compile.

  • Semantic tokens only. Never raw palette values. A test enforces this.
  • Keyboard-operable controls, focus-visible rings and forwarded ARIA are the floor, not a feature.
  • Theme forcing is class-based. .light or .dark on <html> pins color-scheme; with neither class, the OS decides.
  • Add a component in tcpsystems/ui when two products need it; product markup stays in the product repo. Library tests: pnpm test in tcpsystems/ui.