Getting Started

From install to interactive showcase in under 2 minutes.

Prerequisites

  • React 18+
  • TypeScript 5+
  • Node.js 18+ or Bun

Install

bash
bun add jc

Peer dependencies: react and react-dom (18+).

Extract

bash
bunx jc extract

Scans your component files (default: src/components/ui/**/*.tsx), parses TypeScript prop interfaces via react-docgen-typescript, and writes two files:

FileContents
meta.jsonComponent names, prop types, defaults, descriptions, enum values, @example presets
registry.tsLazy import() map keyed by component display name

Create your page

tsx
// src/app/showcase/page.tsx
'use client'

import type { JcMeta } from 'jc'
import { ShowcaseApp } from 'jc'
import meta from '@/jc/generated/meta.json'
import { registry } from '@/jc/generated/registry'

export default function ShowcasePage() {
  return (
    <ShowcaseApp
      meta={meta as unknown as JcMeta}
      registry={registry}
    />
  )
}

Why 'use client'?

ShowcaseApp uses React hooks, localStorage, and history.replaceState. It must render in a client context.

Or use the Next.js adapter for zero boilerplate:

tsx
// src/app/showcase/page.tsx
import { createShowcasePage } from 'jc/next'
import meta from '@/jc/generated/meta.json'
import { registry } from '@/jc/generated/registry'

export default createShowcasePage({ meta, registry })

Add fixtures

Props typed as React components (like icon?: LucideIcon) need concrete values. Fixture plugins provide them with visual pickers.

tsx
import { defineFixtures } from 'jc'
import { Star, Heart, Zap, Download, Trash2 } from 'lucide-react'
import { createElement } from 'react'

function icon(Comp: typeof Star, size = 20) {
  return {
    render: () => createElement(Comp, { size }),
    renderPreview: () => createElement(Comp, { size: 14 }),
    component: Comp,
  }
}

export const lucideFixtures = defineFixtures({
  name: 'lucide',
  fixtures: [
    { key: 'star', label: 'Star', category: 'icons', ...icon(Star) },
    { key: 'heart', label: 'Heart', category: 'icons', ...icon(Heart) },
    { key: 'zap', label: 'Zap', category: 'icons', ...icon(Zap) },
    { key: 'download', label: 'Download', category: 'icons', ...icon(Download) },
    { key: 'trash', label: 'Trash', category: 'icons', ...icon(Trash2) },
  ],
})

Pass fixtures to ShowcaseApp:

tsx
<ShowcaseApp
  meta={meta as unknown as JcMeta}
  registry={registry}
  fixtures={[lucideFixtures]}
/>

Watch mode

bash
bunx jc extract --watch

Watches your component files and re-extracts on save with 200ms debounce. Run alongside your dev server for instant feedback when you add or change props.

What the showcase gives you

AreaDescription
SidebarSearchable component list grouped by directory
PreviewLive component render with checkered background
ControlsAuto-generated prop editor — text, number, boolean, select, component picker
Code outputCopy-pasteable JSX that updates as you change props
HeaderTheme toggle (auto/light/dark) and viewport picker (full/375/768/1280px)