The unified UI library powering Bigtablet products.
Crafted for clarity. Built on tokens. Ships with dark mode.
Documentation · Storybook · NPM · 🇰🇷 한국어
import { ThemeProvider, Button, Modal, useToast } from "@bigtablet/design-system";
// No CSS import needed - each component brings its own CSS plus the shared theme variables,
// so a page that uses only Button ships about 3 kB of DS CSS (gzip) instead of 20 kB.
// Next.js with webpack: add the package to `experimental.optimizePackageImports` (Turbopack needs nothing).
export default function App() {
const toast = useToast();
return (
<ThemeProvider>
<Button onClick={() => toast.success("Saved")}>Save</Button>
</ThemeProvider>
);
}A complete React + TypeScript design system maintained by Bigtablet for internal product work. Open-sourced for reference - external use welcome, but minor versions may include breaking changes.
- 40+ components across forms, display, feedback, navigation, overlay, and layout
- 13 token domains - colors, typography, spacing, motion, radius, elevation, and more - exposed as SCSS variables and CSS custom properties (plus a SCSS-only
layoutdomain) - Light + dark mode out of the box.
[data-theme="dark"]orprefers-color-scheme, no theme provider required (but available viaThemeProviderfor runtime toggling) - Vanilla JS bundle for non-React backends - Thymeleaf, JSP, PHP, Django
- Accessibility tested with axe-core in CI · keyboard nav · ARIA throughout
pnpm add @bigtablet/design-system react@^19 react-dom@^19 lucide-reactRequires React 19 + lucide-react ≥ 0.552. Next.js is an optional peer dependency at >=15.
One-line setup - auto-detect package manager + framework
curl -fsSL https://raw.githubusercontent.com/Bigtablet/bigtablet-design-system/main/scripts/setup.sh | shDetects npm / yarn / pnpm / bun and React / Next.js, installs deps, prints CSS + provider setup steps.
import { ThemeProvider, AlertProvider, ToastProvider } from "@bigtablet/design-system";
<ThemeProvider>
<AlertProvider>
<ToastProvider>{children}</ToastProvider>
</AlertProvider>
</ThemeProvider>Use the hooks anywhere:
const toast = useToast();
const { showAlert } = useAlert();
toast.success("Saved");
showAlert({ title: "Delete?", showCancel: true, onConfirm: ... });| Forms | Button · IconButton · CopyButton · TextField · Textarea · Checkbox · Radio · RadioGroup · SegmentedControl · Toggle · Dropdown · FilterBar · DatePicker · DateCalendar · FileInput · ImageCropper · OtpInput |
| Display | Card · MediaCard · Hero · Avatar · Badge · Chip · ListItem · Table · Divider · Icon · Accordion |
| Feedback | Alert · Toast · InlineAlert · Spinner · TopLoading · LinearProgress · Skeleton · EmptyState · ErrorState |
| Navigation | Tabs · Sidebar · BottomNav · NavBar · Breadcrumb · Menu · Pagination |
| Overlay | Modal · Drawer · Tooltip · Popover |
| Layout | Container · Section · Stack · Grid |
| System | ThemeProvider |
→ Full API · docs/COMPONENTS.md
@use "@bigtablet/design-system/scss/token" as token;
.card {
background: token.$color_bg_solid;
color: token.$color_text_heading;
padding: token.$spacing_16;
border-radius: token.$radius_md;
box-shadow: token.$elevation_level1;
}/* from @bigtablet/design-system/style.css */
.card {
background: var(--bt-color-bg-solid);
color: var(--bt-color-text-heading);
border: 1px solid var(--bt-color-border-default);
box-shadow: var(--bt-elevation-level1);
}The React entry's
style.cssonly emits--bt-color-*,--bt-elevation-*,--bt-focus-*,--bt-sidebar-*,--bt-bottom-nav-*,--bt-bottom-inset*,--bt-scrollbar-width,--bt-z-*,--bt-radius-*,--bt-spacing-*,--bt-font-family. Font size and line height are SCSS-only on this entry - use thescss/tokentypography mixins (--bt-font-size-*exists only in the Vanilla bundle).
colors · spacing · typography · radius · elevation · motion · z-index · breakpoints · border-width · opacity · skeleton · icon · a11y · layoutSCSS only
/* app/globals.css - import before tailwindcss so the layer order is fixed first */
@import "@bigtablet/design-system/tailwind.css";
@import "tailwindcss";import "@bigtablet/design-system/style.css"; // defines the --bt-* values
<p className="text-bt-text-heading shadow-bt-level2 dark:bg-bt-bg-solid" />tailwind.css maps every --bt-color-* to --color-bt-*, --bt-elevation-* / --bt-focus-ring* to --shadow-bt-*, --bt-radius-* to --radius-bt-* (rounded-bt-md), --bt-spacing-* to --spacing-bt-* (p-bt-16) and --bt-font-family to --font-bt (font-bt) (values stay var(), so dark mode and your overrides follow), and makes dark: match ThemeProvider (data-theme="dark", or OS dark when data-theme is unset). Component CSS lives in the bigtablet cascade layer (theme, base, reset, bigtablet, components, utilities), so utilities and your own unlayered CSS override it without specificity fights: <Button className="bg-bt-text-brand" />. Element-selector resets of your own (* { padding: 0 }, button { background: none }) and global focus styles (:focus-visible { outline: 2px solid ... }) must go in @layer reset { ... } - unlayered, they beat every DS component, and a global :focus-visible outline is drawn on top of the DS focus ring (a double ring).
For server-rendered apps (Thymeleaf, JSP, PHP, Django):
<link rel="stylesheet" href="https://unpkg.com/@bigtablet/design-system/dist/vanilla/bigtablet.min.css">
<script src="https://unpkg.com/@bigtablet/design-system/dist/vanilla/bigtablet.min.js"></script>
<button class="bt-button bt-button--md bt-button--filled">Filled</button>→ Full guide · docs/VANILLA.md
pnpm install
pnpm storybook # localhost:6006
pnpm test # Vitest unit
pnpm test:storybook # a11y + Playwright
pnpm build # tsup + SCSS copyThe published Storybook lives at bigtablet.github.io/bigtablet-design-system and redeploys from main.
| 📚 Components | Props API + usage per component |
| 🔄 Migration | Deprecated prop migration guide |
| 🎨 Theming | Light/dark theme system guide |
| 🏗️ Architecture | Project structure + design principles |
| 🤝 Contributing | Dev setup + workflow |
| 🧪 Testing | Test patterns + a11y testing |
| 🌐 Vanilla JS | HTML/CSS/JS integration |
Licensed under the Bigtablet License.