BOXY

Packages

Components for the framework you already use

Nine native packages, one source. Each is generated from a single component spec and tested against the same 826 golden cases, so a Boxy Button in Angular and a Boxy Button in Elm render the markup the stylesheet expects.

npm install @boxy-design/react

React 19 · setup

  • Import the stylesheet once at the app root: import "@boxy-design/react/styles.css".
  • Render <IconSprite /> once near the root so <Icon name="..." /> resolves.
  • Optional: <ThemeScript /> in <head> (SSR) and useBoxy() for theme, density and mode.
  • Render <Behaviors /> once near the root to make menus, tooltips, combobox, calendar, kanban and the other interactive widgets respond. Tabs, Modal and Drawer are components and need nothing.
tsx
import { Button, Field, Input } from "@boxy-design/react";

<Field label="Service name" help="Lowercase, hyphens only.">
  <Input />
</Field>
<Button variant="primary">Deploy</Button>

Notes

  • Field wires id, aria-describedby and aria-invalid into the control inside it; do not set them by hand.
  • Extend with className, never by overriding bx-* classes. buttonClass() and the other *Class() builders give the same classes for a non-Boxy element.

MIT · one version across every package · shares the stylesheet and tokens

01 / Why they match

Generated, then checked five ways

Nobody ports Boxy by hand. A component is described once, as a framework-neutral element tree, and each package is emitted from that description. Then every layer that could drift has its own test.

source of truth
boxy-components.css        the bx-* classes: what it looks like
spec/components.json       element tree, props, a11y: what it is
        |
        v  node tools/gen/build.mjs
packages/<framework>/src/generated/   emitted, committed, diffed in CI

01

Spec against CSS

The build fails if the spec names a class or icon that does not exist, or if the stylesheet has a modifier no component exposes.

02

Spec against this site

Every spec'd component is parsed out of these showcase pages. A usage the spec cannot produce, such as a different role or child order, fails the build.

03

Output against spec

CI regenerates everything and fails if a committed file differs. A markup change shows up as a diff in the golden cases, so it gets reviewed.

04

Every package, same cases

Each package renders all 826 cases through its own compiler and runtime, then diffs the DOM against the oracle. Angular is built AOT, Elm is type-checked.

05

Behaviour

Keyboard navigation, focus trap, scroll lock, inert page and focus return are tested in a DOM. Next and Nuxt are also built as real apps and their server HTML is asserted.

06

Sabotage checks

Breaking a class name, a role or a child element on purpose must turn the suites red. That is how a stale test cache in the Angular runner was found.

02 / Coverage

What the packages include today

230 component parts, the same in every package: everything in the stylesheet, from buttons and forms to menus, the combobox, the calendar, kanban boards, the data grid and the agent chat. The twelve page patterns are compositions of these, so they are built from the same parts.

GroupComponents
ButtonsButton, ButtonGroup
FormsLabel, HelpText, Field, Input, Textarea, Select, Choice, Checkbox, Radio, Toggle, SearchField, DateField, Slider, SliderScale, SliderTicks, Stepper, Segmented
Combobox and pickersCombo, ComboToggle, Listbox, ListboxGroup, ListboxEmpty, ListboxOption, OptionMeta, MultiSelect, MultiInput, MultiClear, Calendar, RangeCalendar, CalendarFoot, RangePicker, RangePresets, ColorPicker, PickerField, PickerHue, PickerRow, PickerSwatches, PickerContrast, Swatch, SwatchButton
LayoutStack, Cluster, Grid, AutoGrid, Split, Collapse, Container, Rail, Section, GridBackground, DotBackground, Ticks
Text and contentLabelText, Mono, Num, ScreenReaderText, Kbd, Mark, Code, Caret, Prose, Quote, Cite, List, OrderedList, ListItem, DescriptionList, Empty, EmptyGlyph, Banner
Status and feedbackIcon, Tag, TagRemove, Status, Callout, Spinner, Skeleton, Progress, ProgressRow, Meter, MeterCell, StepBar, StepBarCell, Toast, ToastBody, ToastStack, Tooltip
People and activityAvatar, AvatarGroup, Timeline, TimelineItem, TimelineTime, TimelineTitle, TimelineBody
Cards and dataCard, CardHead, CardBody, CardFoot, Table, TableWrap, Th, Td, DataGrid, DataGridBar, Chart, ChartLegend, ChartKey, ChartTip, Sparkline, UptimeStrip
NavigationTabs, TabList, Tab, TabPanel, Breadcrumb, BreadcrumbMore, Tree, TreeHeading, TreeLink, TreeSummary, TreeCount, Toc, TocLink, Accordion, AccordionNumber, AccordionBody
Menus and popoversMenu, MenuEntry, MenuItem, MenuLink, MenuItemCheckbox, MenuItemRadio, MenuIcon, MenuHint, MenuLabel, MenuSeparator, MenuHeader, MenuFooter, Popover, PopoverHead, PopoverBody, PopoverFoot, FloatingPanel
Dialogs, drawers and paletteModal, Dialog, DialogHeader, DialogTitle, DialogBody, DialogFooter, Scrim, Drawer, DrawerPanel, DrawerHead, DrawerBody, DrawerFoot, PaletteSearch, PaletteList, PaletteGroup, PaletteLink, PaletteAction, PaletteMeta, PaletteEmpty, PaletteFoot
CodeCodeBlock, CodeBlockHead, CodeBlockSpacer, CodeBlockButton, CodeBlockFoot, CodeLines, CodeLine, Token
FilesDropzone, DropzoneGlyph, UploadList, UploadItem, UploadType, UploadName, UploadMeta
Agent and chatThread, Message, MessageWho, MessageMeta, MessageBody, MessageActions, Thought, ThoughtBody, ToolList, Tool, ToolStatus, ToolName, ToolArgs, ToolDuration, ToolBody, ToolSummary, Approval, ApprovalHead, ApprovalBody, ApprovalFoot, Composer, ComposerFiles, ComposerBar
Boards and panesKanban, KanbanColumn, KanbanHead, KanbanCount, KanbanList, KanbanSlot, KanbanCard, KanbanCardTitle, KanbanCardMeta, KanbanPriority, Panes, Pane, PaneHead, Resizer
NotificationsBellButton, BellCount, Inbox, InboxHead, InboxTabs, InboxList, InboxDay, InboxFoot, Note, NoteIcon, NoteText, NoteActions, NoteTime

Names follow each framework's convention: Angular prefixes with Bx, Elm has one module per component, HTMX uses lower-case functions and ships ready-made partials/*.html.

03 / Behaviours

One behaviour layer under all of them

Menus with submenus and type-ahead, tooltips, the combobox and multi-select, the calendar and range picker, kanban drag, resizable panes, the editable grid, the colour picker, the inbox, charts and toasts need JavaScript. It is written once, in @boxy-design/behaviors, finds widgets by their classes and data attributes, and has no framework in it. Every package starts it with one line.

start it
React, Next, Preact, Svelte   <Behaviors />
Vue                          <Behaviors />  or  useBehaviors()
Angular                      provideBoxyBehaviors()
Nuxt                         automatic
HTMX, Elm                    <script src="boxy-htmx.js">  /  boxy-behaviors.js

Tabs, Modal and Drawer are native components in every framework package, so they need nothing. Your app hears about changes through bubbling bx:* events, such as bx:select, bx:date and bx:move (cancelable, so a framework that owns the cards can move them itself).

04 / Theme

Theme, density and mode work the same everywhere

Every web package exports the same no-flash script and helpers. They set data-theme, data-density and data-mode on <html> and keep them under boxy:theme, boxy:density and boxy:mode, which is also what this site does. React, Next, Vue and Nuxt add a reactive useBoxy().

05 / For agents

Your agent picks the right package

Installing the skill also installs the rule: if the project uses one of these frameworks, use its package and do not hand-write components. The CLI reads package.json (and elm.json) to say which one.

terminal
$ npx boxy-design packages
# prints the package for this project, with setup and an example

npx boxy-design init prints the same note, and the skill's references/frameworks.md carries the per-framework setup. Agents still run boxy-check before they report the work done.

Start

Install one package and keep the system intact

The stylesheet, the tokens and the components move together, so an upgrade is one version number.