{"id":48235489,"url":"https://github.com/cerberauth/design-system","last_synced_at":"2026-04-04T19:59:02.384Z","repository":{"id":347447660,"uuid":"1185729448","full_name":"cerberauth/design-system","owner":"cerberauth","description":null,"archived":false,"fork":false,"pushed_at":"2026-03-28T00:05:03.000Z","size":240,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-28T05:50:22.641Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cerberauth.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-18T22:16:03.000Z","updated_at":"2026-03-28T00:04:34.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/cerberauth/design-system","commit_stats":null,"previous_names":["cerberauth/design-system"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/cerberauth/design-system","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cerberauth%2Fdesign-system","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cerberauth%2Fdesign-system/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cerberauth%2Fdesign-system/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cerberauth%2Fdesign-system/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cerberauth","download_url":"https://codeload.github.com/cerberauth/design-system/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cerberauth%2Fdesign-system/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31411545,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T19:29:44.979Z","status":"ssl_error","status_checked_at":"2026-04-04T19:29:11.535Z","response_time":60,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-04T19:58:58.724Z","updated_at":"2026-04-04T19:59:02.375Z","avatar_url":"https://github.com/cerberauth.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @cerberauth/design-system\n\nInternal monorepo for the CerberAuth Design System, publishing two independent packages:\n\n| Package | Version | Description |\n|---|---|---|\n| `@cerberauth/tokens` | ![npm](https://img.shields.io/npm/v/@cerberauth/tokens) | Framework-agnostic CSS design tokens |\n| `@cerberauth/ui` | ![npm](https://img.shields.io/npm/v/@cerberauth/ui) | Shared React components (Shadcn/ui-based) |\n\n## Repository structure\n\n```\ndesign-system/\n├── apps/\n│   └── storybook/          # Storybook 8 + Vite — component documentation\n├── packages/\n│   ├── tokens/             # CSS design tokens (no build step)\n│   ├── ui/                 # React components (tsup, ESM + CJS)\n│   ├── tsconfig/           # Shared TypeScript base config\n│   └── eslint-config/      # Shared ESLint flat config\n├── turbo.json\n└── pnpm-workspace.yaml\n```\n\n## Getting started\n\n### Install \u0026 build\n\n```bash\npnpm install\npnpm build      # builds @cerberauth/ui (tokens has no build step)\n```\n\n### Run Storybook\n\n```bash\npnpm storybook  # opens http://localhost:6006\n```\n\n---\n\n## Adding a new component\n\n1. **Create the component file** in `packages/ui/src/components/my-component.tsx`:\n\n```tsx\nimport * as React from \"react\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"../lib/utils\";\n\nconst myComponentVariants = cva(\n  \"base-classes-here\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-fg\",\n        // add variants...\n      },\n    },\n    defaultVariants: { variant: \"default\" },\n  }\n);\n\nexport interface MyComponentProps\n  extends React.HTMLAttributes\u003cHTMLDivElement\u003e,\n    VariantProps\u003ctypeof myComponentVariants\u003e {}\n\nfunction MyComponent({ className, variant, ...props }: MyComponentProps) {\n  return (\n    \u003cdiv\n      data-slot=\"my-component\"\n      className={cn(myComponentVariants({ variant }), className)}\n      {...props}\n    /\u003e\n  );\n}\n\nexport { MyComponent, myComponentVariants };\n```\n\n2. **Export it** from `packages/ui/src/index.ts`:\n\n```ts\nexport { MyComponent, myComponentVariants } from \"./components/my-component\";\nexport type { MyComponentProps } from \"./components/my-component\";\n```\n\n3. **Add a story** in `apps/storybook/stories/my-component.stories.tsx`:\n\n```tsx\nimport type { Meta, StoryObj } from \"@storybook/react\";\nimport { MyComponent } from \"@cerberauth/ui\";\n\nconst meta: Meta\u003ctypeof MyComponent\u003e = {\n  title: \"Components/MyComponent\",\n  component: MyComponent,\n  tags: [\"autodocs\"],\n};\n\nexport default meta;\ntype Story = StoryObj\u003ctypeof MyComponent\u003e;\n\nexport const Default: Story = {};\n```\n\n4. **Rebuild** the package:\n\n```bash\npnpm --filter @cerberauth/ui build\n```\n\n---\n\n## Consuming the packages\n\n### Next.js (App Router + Tailwind CSS v4)\n\n**Install:**\n\n```bash\npnpm add @cerberauth/tokens @cerberauth/ui\n```\n\n**`app/globals.css`** — replace your existing Tailwind import:\n\n```css\n@import \"@cerberauth/tokens/css\";\n\n/* Scan component files for Tailwind class usage */\n@source \"../../node_modules/@cerberauth/ui/dist\";\n```\n\n**`next.config.ts`** — no changes needed; the CSS import handles everything.\n\n**`app/layout.tsx`:**\n\n```tsx\nimport \"./globals.css\";\n\nexport default function RootLayout({ children }: { children: React.ReactNode }) {\n  return (\n    \u003chtml lang=\"en\"\u003e\n      \u003cbody\u003e{children}\u003c/body\u003e\n    \u003c/html\u003e\n  );\n}\n```\n\n**Dark mode** — add `data-theme=\"dark\"` to the `\u003chtml\u003e` element. Works with any dark-mode library (next-themes, etc.):\n\n```tsx\n// With next-themes\n\u003chtml data-theme={resolvedTheme === \"dark\" ? \"dark\" : \"\"}\u003e\n```\n\n**Usage:**\n\n```tsx\nimport { Button, Card, CardContent, Input, Badge } from \"@cerberauth/ui\";\n\nexport default function Page() {\n  return (\n    \u003cCard className=\"w-80\"\u003e\n      \u003cCardContent className=\"pt-6 flex flex-col gap-4\"\u003e\n        \u003cInput label=\"Email\" placeholder=\"you@example.com\" type=\"email\" /\u003e\n        \u003cButton\u003eSign in\u003c/Button\u003e\n        \u003cBadge variant=\"secondary\"\u003eBeta\u003c/Badge\u003e\n      \u003c/CardContent\u003e\n    \u003c/Card\u003e\n  );\n}\n```\n\n---\n\n### Astro (@astrojs/react + Tailwind CSS v4)\n\n**Install:**\n\n```bash\npnpm add @cerberauth/tokens @cerberauth/ui\npnpm add -D @tailwindcss/vite\n```\n\n**`astro.config.mjs`:**\n\n```js\nimport { defineConfig } from \"astro/config\";\nimport react from \"@astrojs/react\";\nimport tailwindcss from \"@tailwindcss/vite\";\n\nexport default defineConfig({\n  integrations: [react()],\n  vite: {\n    plugins: [tailwindcss()],\n  },\n});\n```\n\n**`src/styles/global.css`:**\n\n```css\n@import \"@cerberauth/tokens/css\";\n\n@source \"../../node_modules/@cerberauth/ui/dist\";\n```\n\n**`src/layouts/Layout.astro`:**\n\n```astro\n---\nimport \"../styles/global.css\";\n---\n\u003chtml lang=\"en\"\u003e\n  \u003cbody\u003e\n    \u003cslot /\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\n**Dark mode** — Astro SSR sets `data-theme` server-side (no JavaScript required):\n\n```astro\n---\nconst theme = Astro.cookies.get(\"theme\")?.value ?? \"light\";\n---\n\u003chtml lang=\"en\" data-theme={theme === \"dark\" ? \"dark\" : \"\"}\u003e\n```\n\n**Usage in React islands:**\n\n```tsx\n// src/components/LoginForm.tsx\nimport { Button, Input } from \"@cerberauth/ui\";\n\nexport function LoginForm() {\n  return (\n    \u003cform className=\"flex flex-col gap-4\"\u003e\n      \u003cInput label=\"Email\" type=\"email\" placeholder=\"you@example.com\" /\u003e\n      \u003cInput label=\"Password\" type=\"password\" placeholder=\"••••••••\" /\u003e\n      \u003cButton type=\"submit\"\u003eSign in\u003c/Button\u003e\n    \u003c/form\u003e\n  );\n}\n```\n\n```astro\n---\nimport { LoginForm } from \"../components/LoginForm\";\n---\n\u003cLoginForm client:load /\u003e\n```\n\n---\n\n## Releasing packages\n\nThis monorepo uses [Changesets](https://github.com/changesets/changesets) for independent versioning.\n\n```bash\n# 1. Create a changeset describing your changes\npnpm changeset\n\n# 2. Version packages (bumps versions + updates changelogs)\npnpm version-packages\n\n# 3. Build and publish to npm\npnpm release\n```\n\n`@cerberauth/tokens` and `@cerberauth/ui` can be released on separate schedules.\n\n---\n\n## Token architecture\n\n```\nprimitives.css          raw scale values (--primitive-blue-600, --primitive-space-4, …)\n    ↓\nsemantic.css            intent aliases (--token-primary, --token-bg, --token-fg, …)\n    ↓\ndark.css                dark mode overrides ([data-theme=\"dark\"] { --token-primary: … })\n    ↓\nindex.css               @theme inline { --color-primary: var(--token-primary) }\n                        generates Tailwind utilities: bg-primary, text-fg, rounded-md, …\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcerberauth%2Fdesign-system","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcerberauth%2Fdesign-system","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcerberauth%2Fdesign-system/lists"}