npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@boostdev/design-system-components

v1.2.1

Published

BoostDev React component library: accessible, token-driven components built on @boostdev/design-system-foundation

Readme

@boostdev/components

Accessible, token-driven React components built on @boostdev/design-system-foundation. Zero extra runtime — bring your own CSS reset and token layer, then import the components.

Installation

pnpm add @boostdev/components @boostdev/design-system-foundation
npm install @boostdev/components @boostdev/design-system-foundation
yarn add @boostdev/components @boostdev/design-system-foundation

@boostdev/design-system-foundation is a required peer dependency. The components rely on its CSS custom properties for all colour, spacing, and typography values.

Setup

Import the design system tokens and the component styles once at your app root:

/* app.css */
@import "@boostdev/design-system-foundation/css";
@import "@boostdev/components/css";

Or with a JS bundler (Vite, Next.js, etc.):

// main.ts / layout.tsx
import '@boostdev/design-system-foundation/css';
import '@boostdev/components/css';

All component styles live inside @layer component, which sits above the token layers in the cascade. You can override any component from outside without specificity fights.


Next.js / React Server Components

The main @boostdev/components entry has no 'use client' directive. When Next.js evaluates the bundle in a React Server Component context, components that call createContext (e.g. Toast) will crash at module evaluation time.

Use the /client subpath instead — it is identical in API but has 'use client' prepended to the bundle, which tells Next.js to treat it as client-only code:

// Plain React / Vite — unchanged
import { Button, Card } from '@boostdev/components';

// Next.js / RSC — use the /client subpath
import { Button, Card } from '@boostdev/components/client';

Usage

UI components

Badge

import { Badge } from '@boostdev/components';

<Badge>New</Badge>
<Badge variant="success">Active</Badge>
<Badge variant="error">Failed</Badge>
<Badge variant="warning">Pending</Badge>
<Badge variant="secondary">Draft</Badge>

Variants: primary (default) · secondary · success · error · warning


Collapsible

import { Collapsible } from '@boostdev/components';

<Collapsible summary="What is the return policy?" defaultOpen>
  You can return any item within 30 days of purchase.
</Collapsible>

{/* Group: only one open at a time */}
<Collapsible name="faq" summary="Question 1">Answer 1</Collapsible>
<Collapsible name="faq" summary="Question 2">Answer 2</Collapsible>

Built on native <details>/<summary>. Use name to group multiple Collapsibles so only one stays open at a time.


Typography

import { Typography } from '@boostdev/components';

<Typography variant="h1">Page title</Typography>
<Typography variant="h2">Section title</Typography>
<Typography variant="body">Paragraph text</Typography>
<Typography variant="body_s">Small print</Typography>

Pass component to override the rendered element without changing the visual style:

<Typography variant="h2" component="h3">Visually h2, semantically h3</Typography>

Variants: h1 · h2 · h3 · body (default) · body_s


Loading

import { Loading } from '@boostdev/components';

<Loading />
<Loading size="small" />
<Loading size="large" />

Sizes: small · medium (default) · large


Skeleton

import { Skeleton } from '@boostdev/components';

<Skeleton className="w-48 h-4" />

Renders an aria-hidden shimmer block. Size it with a className or inline style.


Interaction components

Button

import { Button } from '@boostdev/components';

<Button>Click me</Button>
<Button variant="ghost">Cancel</Button>
<Button size="small">Small</Button>
<Button href="/dashboard">Link button</Button>
<Button iconStart={<Icon />} aria-label="Delete" />
<Button hasPulse>Call to action</Button>

| Prop | Type | Default | |---|---|---| | variant | 'default' \| 'ghost' | 'default' | | size | 'small' \| 'medium' \| 'large' | 'medium' | | href | string | — renders an <a> | | iconStart | ReactNode | — | | iconEnd | ReactNode | — | | hasPulse | boolean | false | | disabled | boolean | false |

Variants:

  • default — filled with --button_color (CTA green). Hover transitions to an outlined state.
  • ghost — transparent background, border and text use --button_color. Hover fills.

Re-theming — set two CSS custom properties to change the colour of both variants:

.danger-zone .my-button {
  --button_color:    var(--bds-error);
  --button_on-color: var(--bds-on-error);
}

Dialog

import { Dialog } from '@boostdev/components';

<Dialog isOpen={open} onClose={() => setOpen(false)}>
  <h2>Confirm</h2>
  <p>Are you sure?</p>
</Dialog>

Renders a native <dialog> element with a dimmed, blurred backdrop. isOpen controls open/close; onClose is called when the close button is pressed or the backdrop is clicked. Dialog traps focus while open and restores focus to the triggering element on close.

Override the backdrop colour via --color_backdrop (default: rgb(0 0 0 / 50%)).


Rating

import { Rating } from '@boostdev/components';

<Rating value={3} />
<Rating value={4} max={10} />

max defaults to 5. Stars are rendered as SVG icons; unfilled stars use the current background colour.


Toast

import { ToastProvider, useToast } from '@boostdev/components';

// Wrap your app (or layout) once:
<ToastProvider>
  <App />
</ToastProvider>

// Inside any component:
function SaveButton() {
  const { showToast } = useToast();
  return (
    <button onClick={() => showToast('Saved!', 'success')}>
      Save
    </button>
  );
}

showToast(message, variant) — variant: 'success' · 'error' · 'info'

Toasts auto-dismiss after 5 seconds.


Form components

All form components accept standard HTML input attributes via spread in addition to their own props.

FormInput

import { FormInput } from '@boostdev/components';

<FormInput
  label="Email"
  name="email"
  type="email"
  hint="We'll never share your email"
  error={errors.email}
/>

Checkbox

import { Checkbox, CheckboxGroup } from '@boostdev/components';

<Checkbox
  label="I agree to the terms"
  name="agree"
  error={errors.agree}
/>

Group multiple checkboxes with a shared label using CheckboxGroup:

<CheckboxGroup legend="Notifications" required error={errors.notifications}>
  <Checkbox label="Email" name="notify_email" />
  <Checkbox label="SMS" name="notify_sms" />
  <Checkbox label="Push" name="notify_push" />
</CheckboxGroup>

Radio

import { Radio, RadioGroup } from '@boostdev/components';

<RadioGroup legend="Preferred contact" required>
  <Radio label="Option A" name="choice" value="a" description="Optional supporting text." />
  <Radio label="Option B" name="choice" value="b" />
</RadioGroup>

Switch

import { Switch } from '@boostdev/components';

<Switch label="Enable notifications" name="notifications" />
<Switch label="Dark mode" name="dark-mode" defaultChecked />
<Switch label="On" name="theme" prefix="Off" size="small" />

Sizes: small · medium (default) · large

SegmentedControl

import { SegmentedControl } from '@boostdev/components';

<SegmentedControl
  name="view"
  defaultValue="week"
  aria-label="Calendar view"
  options={[
    { value: 'day',   label: 'Day'   },
    { value: 'week',  label: 'Week'  },
    { value: 'month', label: 'Month' },
  ]}
  onChange={value => console.log(value)}
/>

Single-select control with a sliding thumb. All options have equal width (sized to the widest). Sizes: small · medium (default) · large.


Layout components

ButtonGroup

import { ButtonGroup, Button } from '@boostdev/components';

<ButtonGroup variant="flow" aria-label="Page navigation">
  <Button>Back</Button>
  <Button>Next</Button>
</ButtonGroup>

| Prop | Type | Default | |---|---|---| | variant | 'flow' \| 'card' \| 'modal' \| 'content' | — | | aria-label | string | — recommended when group purpose isn't clear from context |


Card

import { Card } from '@boostdev/components';

<Card>Basic card</Card>
<Card variant="elevated" padding="large">Elevated</Card>
<Card variant="outlined" textAlign="center">Outlined</Card>
<Card onClick={() => navigate('/detail')}>Clickable card</Card>

| Prop | Type | Default | |---|---|---| | variant | 'default' \| 'elevated' \| 'outlined' | 'default' | | padding | 'none' \| 'small' \| 'medium' \| 'large' | 'medium' | | textAlign | 'start' \| 'center' \| 'end' | 'start' | | onClick | () => void | — renders a <button> |


SectionHeader

import { SectionHeader } from '@boostdev/components';

<SectionHeader title="Our services" />
<SectionHeader
  title="Welcome"
  subtitle="Everything you need in one place"
  size="large"
  alignment="center"
/>

| Prop | Type | Default | |---|---|---| | title | string | required | | subtitle | string | — | | size | 'small' \| 'medium' \| 'large' | 'medium' | | alignment | 'start' \| 'center' \| 'end' | 'start' |


IconWrapper

import { IconWrapper } from '@boostdev/components';

<IconWrapper>
  <svg>...</svg>
</IconWrapper>

{/* Mark as decorative when accompanied by a visible label */}
<IconWrapper aria-hidden>
  <svg>...</svg>
</IconWrapper>

Renders a circular container sized to its own font-size. Override the background colour via the --icon-wrapper-color CSS custom property. Pass aria-hidden when the icon is decorative.


Utilities

cn

Composes class name strings, filtering out falsy values:

import { cn } from '@boostdev/components';

cn('card', isActive && 'card--active', [extraClass])
// → "card card--active extraClass"

Overriding component styles

Every component exposes CSS custom properties as a styling API. Set them on a parent or via style to adjust the component without writing extra CSS:

/* Override the button colour for a specific context */
.hero .button {
  --button_color:    var(--bds-brand);
  --button_on-color: var(--bds-on-brand);
}

All component styles sit in @layer component. You can also write rules in a higher layer:

@layer my-overrides {
  .my-button {
    border-radius: 0;
  }
}

Overriding active/checked state colour

Components with a checked or filled state (Checkbox, Radio, Slider, Progress, ProgressCircle) expose a component-scoped variable that falls back to the global --bds-active token:

/* Override the active colour for a single checkbox */
.my-checkbox {
  --checkbox_color-active:    var(--bds-brand);
  --checkbox_color-on-active: var(--bds-on-brand);
}

/* Override for all sliders in a section */
.settings-panel {
  --slider_color-active: var(--bds-important);
}

The two-level chain means you can also override at the global token level — see Theming below.


Theming

Components inherit from @boostdev/design-system-foundation tokens. Override semantic tokens to retheme all components at once:

/* tokens.config.css — import after the design system CSS */
@layer tokens.override {
  :root {
    --bds-cta:        var(--bds-BASE__color--orange);
    --bds-on-cta:     var(--bds-BASE__color--white);
    --bds-interactive: var(--bds-BASE__color--orange);
  }
}

Active state tokens

The --bds-active family controls the checked/filled/selected colour across all form controls and progress indicators. Override it once to retheme checkboxes, radio buttons, sliders, progress bars, and the switch thumb simultaneously:

@layer tokens.override {
  :root {
    --bds-active:            var(--bds-BASE__color--blue);
    --bds-on-active:         var(--bds-BASE__color--white);
    --bds-active--subtle:    var(--bds-BASE__color--blue--100);  /* Switch track */
    --bds-on-active--subtle: var(--bds-BASE__color--blue--900);
    --bds-active--strong:    var(--bds-BASE__color--blue--700);  /* Switch thumb */
    --bds-on-active--strong: var(--bds-BASE__color--white);
  }
}

Dark mode is handled automatically via [data-theme="dark"] or prefers-color-scheme.


Development

pnpm build        # compile to dist/
pnpm typecheck    # TypeScript check (library code only)
pnpm lint         # ESLint
pnpm lint:css     # Stylelint
pnpm test         # Vitest — 364 tests
pnpm mcp:start    # Start the MCP server locally (http://localhost:3001/api/mcp)
pnpm storybook    # Storybook dev server on port 6006

Adding a new component

  1. Create src/components/{category}/{Name}/
  2. Add Name.tsx, Name.module.css, index.ts
  3. Wrap all CSS in @layer component { ... }
  4. Use only design token custom properties — no hard-coded colours, spacing, or font sizes
  5. Re-export from src/index.ts
  6. Run pnpm build && pnpm typecheck && pnpm lint && pnpm lint:css && pnpm test

Design system reference (MCP server)

A live MCP server exposing this design system's components and tokens is deployed at:

https://ds.boostdev.nl/api/mcp

AI coding agents can connect to it to look up component props and design tokens without reading the source code directly. It exposes five tools:

| Tool | Description | |---|---| | ds_list_components | All components grouped by category | | ds_get_component | Full props interface for a named component | | ds_list_tokens | Design tokens, filterable by group | | ds_search | Keyword search across components and tokens | | ds_get_guide | Returns the AGENTS.md usage guide |

To run the MCP server locally:

pnpm mcp:start   # listens on http://localhost:3001/api/mcp

Publishing a new version

npm version patch   # or minor / major
git push --follow-tags

GitLab CI will build and publish to npm automatically on version tags.