Ellie MD Design System
A code-first component library for EllieMD. No Figma handoff. The library is the source of truth -- published as @ellie/ui and consumed across EllieMD's surfaces.
Every token, component, and pattern in this library is sourced directly from production elliemd.com. Colors are sampled, not invented. Typography matches the live site. Interactions follow what patients already experience.
90
Components
3
Layers
Quick start
# Install the package
pnpm add @ellie/ui
# In your app entry point, import the base styles
import '@ellie/ui/styles'
# Then import components
import { Button, Card, Badge, Input } from '@ellie/ui'
<Button variant="primary" size="md">
Get Started
</Button>Architecture
The library is organized in three dependency layers. Foundation provides the tokens that everything above requires. Primitives are the building blocks that Patterns compose into page-level components. Nothing in a higher layer re-implements what the layer below already provides.
Tokens
Colors, typography, shadows, gradients, and radii. Source of truth in tokens/index.ts. Mirrors the CSS variables in globals.css.
Primitives
shadcn-parity building blocks. Every primitive is built on Radix UI, styled with EllieMD tokens, and exported as a named component.
Patterns
EllieMD-specific compound components and page templates assembled from the primitive layer.
Component index
90 documented components across all three layers — tokens, primitives, and page-level patterns.
Stack
Every technology decision is intentional. The stack mirrors what shadcn/ui uses because it is the closest proven blueprint at this scope -- copy-paste architecture, no runtime overhead, full type safety, and first-class accessibility.
React 19
Component layer. Every primitive is a forwardRef + displayName component.
Tailwind v4
Styling. All tokens are CSS custom properties in globals.css.
Radix UI
Accessibility primitives. Dialog, Tabs, Select, Popover, and all interactive components.
CVA
class-variance-authority. Manages variant-to-class mappings for every component.
tailwind-merge + clsx
Safe className merging via the cn() util exported from @ellie/ui.