Cookest
@cookest/ui Components

React — Getting Started

How to install and use @cookest/ui React components in your project.

React — Getting Started

@cookest/ui is a React component library built with React 19, TailwindCSS 4, and Framer Motion. It is published on npm and fully typed, tree-shakeable, and ships with dual ESM/CJS output.

Installation

npm install @cookest/ui
# or
bun add @cookest/ui
# or
pnpm add @cookest/ui

Setup

Import the stylesheet in your app's entry point:

import "@cookest/ui/styles.css";

This loads the CSS custom properties (design tokens) and Google Fonts (Playfair Display + Inter).

TailwindCSS v4 projects

If your project uses TailwindCSS v4, add a @source directive so Tailwind scans the component library's utility classes:

/* globals.css */
@import "tailwindcss";
@import "@cookest/ui/src/styles.css";
@source "../node_modules/@cookest/ui/src";

Alternative: CLI install (shadcn-style)

Instead of installing as a package dependency, copy component source directly into your project:

npx @cookest/ui-cli add button input card

See the CLI docs for full reference.

Usage

import { Button, Card, CardHeader, CardBody, Input, Badge } from "@cookest/ui";

export function RecipeCard() {
  return (
    <Card variant="interactive">
      <CardHeader>
        <Badge variant="success" dot>Active</Badge>
        Pasta Carbonara
      </CardHeader>
      <CardBody>
        <Input label="Servings" type="number" placeholder="4" />
        <Button variant="primary" className="mt-4">
          Start Cooking
        </Button>
      </CardBody>
    </Card>
  );
}

Component API

Button

<Button
  variant="primary"   // "primary" | "secondary" | "ghost" | "danger"
  size="md"           // "sm" | "md" | "lg"
  loading={false}
  disabled={false}
  fullWidth={false}
  iconLeft={<Icon />}
  iconRight={<Icon />}
>
  Label
</Button>

Input

<Input
  label="Email"
  placeholder="you@example.com"
  helperText="We'll never share your email"
  error="Invalid email"
  inputSize="md"              // "sm" | "md" | "lg"
  iconLeft={<MailIcon />}
  fullWidth
/>

Textarea

<Textarea
  label="Recipe Description"
  placeholder="Describe the flavors..."
  maxLength={500}
  showCount
  minRows={4}
  autoResize
/>

Card

<Card variant="default" padding="md">
  <CardHeader>Title</CardHeader>
  <CardBody>Content here</CardBody>
  <CardFooter>
    <Button size="sm">Action</Button>
  </CardFooter>
</Card>
<Modal
  open={isOpen}
  onClose={() => setIsOpen(false)}
  title="Confirm Action"
  size="md"
  footer={
    <>
      <Button variant="ghost" onClick={() => setIsOpen(false)}>Cancel</Button>
      <Button variant="primary">Confirm</Button>
    </>
  }
>
  Are you sure you want to proceed?
</Modal>

Alert

The Alert uses a glassmorphism design with a colored accent bar and ambient shadow.

<Alert
  variant="info"       // "info" | "success" | "warning" | "error"
  size="md"            // "sm" | "md" | "lg"
  title="Heads up"
  dismissible
  onDismiss={() => {}}
>
  Your meal plan has been updated.
</Alert>

Select

<Select
  label="Cuisine"
  options={[
    { value: "italian", label: "Italian" },
    { value: "japanese", label: "Japanese" },
  ]}
  value={selected}
  onChange={setSelected}
  searchable
  placeholder="Choose a cuisine..."
/>

Slider

<Slider
  value={cookTime}
  onChange={setCookTime}
  min={5}
  max={120}
  step={5}
  color="primary"    // "primary" | "blue" | "amber" | "rose"
  size="md"          // "sm" | "md" | "lg"
  showValue
  marks={[
    { value: 5, label: "5m" },
    { value: 60, label: "1h" },
    { value: 120, label: "2h" },
  ]}
/>

Progress

{/* Determinate */}
<Progress value={72} color="primary" showLabel label="Uploading..." />

{/* Indeterminate */}
<Progress color="blue" />

{/* Striped */}
<Progress value={60} striped animated />

Spinner

<Spinner
  color="primary"   // "primary" | "blue" | "amber" | "rose" | "white" | "muted"
  size="md"         // "sm" | "md" | "lg" | "xl"
/>

Tabs

<Tabs
  variant="underline"    // "underline" | "pills" | "boxed"
  defaultTab="overview"
  items={[
    {
      id: "overview",
      label: "Overview",
      content: <OverviewPanel />,
    },
    {
      id: "details",
      label: "Details",
      badge: "3",
      content: <DetailsPanel />,
    },
  ]}
/>

Accordion

<Accordion
  variant="default"      // "default" | "bordered" | "separated"
  multiple={false}
  defaultOpen={["q1"]}
  items={[
    {
      id: "q1",
      title: "What is Cookest?",
      content: <p>A meal planning platform...</p>,
    },
    {
      id: "q2",
      title: "How does it work?",
      subtitle: "Quick overview",
      content: <p>Add ingredients, plan meals...</p>,
    },
  ]}
/>

Storybook

Run the interactive component playground:

cd ui-components
bun run storybook

Storybook launches at http://localhost:6006 with live controls for all 18 components.

Build

bun run build

Outputs to dist/ with:

  • index.js (ESM) + index.cjs (CJS)
  • index.d.ts (TypeScript declarations)
  • styles.css (design tokens + Tailwind)

Publishing

@cookest/ui is published to npm. New versions are released by pushing a ui-v* tag:

# Bump version in package.json, then:
git tag ui-v0.2.0
git push origin ui-v0.2.0

GitHub Actions handles the build and npm publish automatically.

Testing

bun run test            # Run all tests
bun run test:watch      # Watch mode
bun run test:coverage   # With coverage report

On this page