Nychthemeron/docs/superpowers/specs/2026-05-11-library-with-playground-design.md
Matthew L McPeak 302a58c258
Some checks failed
ci / build (push) Failing after 21s
ci / publish (push) Has been skipped
ci / publish-docs (push) Has been skipped
Inital Commit
2026-07-15 20:01:01 -04:00

8.1 KiB

Library with Playground Design

Date: 2026-05-11
Project: nychthemeron
Status: Approved

Overview

Transform nychthemeron from a single Vue app into a monorepo containing a Vue component library built on PrimeVue with Tailwind CSS styling, accompanied by a Storybook playground for interactive documentation and development.

Goals

  • Build a reusable Vue component library with custom Tailwind-based styling on PrimeVue
  • Provide interactive documentation via Storybook for developers and stakeholders
  • Enable fast, hot-reload development workflow
  • Support both components and composables (e.g., date utilities for DatePicker)
  • Keep internal/private — no npm publishing required

Architecture

Monorepo Structure

nychthemeron/
├── packages/
│   ├── library/              # Vue component library
│   │   ├── src/
│   │   │   ├── components/   # Vue components (DatePicker, Button, etc.)
│   │   │   ├── composables/  # Reusable logic (useDate, etc.)
│   │   │   └── index.ts      # Barrel export for all exports
│   │   ├── __tests__/        # Unit tests
│   │   ├── package.json      # Library metadata
│   │   ├── tsconfig.json     # Library TS config
│   │   └── vite.config.ts    # Library build config
│   │
│   └── playground/           # Storybook playground
│       ├── .storybook/
│       │   ├── main.ts       # Storybook configuration
│       │   └── preview.ts    # Global setup (Tailwind, PrimeVue)
│       ├── stories/          # Component stories (.stories.ts)
│       ├── package.json      # Playground metadata
│       ├── tsconfig.json     # Storybook TS config
│       └── tailwind.config.ts # Shared Tailwind config
│
├── package.json              # Root workspace config (bun workspaces)
├── tsconfig.json             # Shared base TS config
├── eslint.config.ts          # Shared ESLint config
├── prettier.config.json      # Shared Prettier config
└── docs/                     # Documentation

Dependency Model

  • Root: Shared dev dependencies (TypeScript, ESLint, Prettier, bun workspace config)
  • Library: Declares PrimeVue, Vue 3 as peer dependencies; exports components + composables
  • Playground: Imports @nychthemeron/library and PrimeVue; bundles Storybook

Technology Stack

Layer Technology
Framework Vue 3
Component Base PrimeVue
Styling Tailwind CSS + custom CSS layer
Build (Library) Vite (library mode)
Build (Playground) Vite + Storybook
Testing Vitest + Vue Test Utils
Package Manager Bun (with workspaces)
Type Checking TypeScript + vue-tsc

Library Package Details

Export Model

index.ts exports all components and composables:

export * from './components'
export * from './composables'

Consumers import as:

import { DatePicker, Button } from '@nychthemeron/library'
import { useDate } from '@nychthemeron/library'

Component Structure

Each component lives in its own folder:

src/components/
├── DatePicker/
│   ├── DatePicker.vue
│   └── DatePicker.spec.ts
├── Button/
│   ├── Button.vue
│   └── Button.spec.ts
└── index.ts

Composables Structure

Reusable logic in src/composables/:

src/composables/
├── useDate.ts          # Date utilities (parsing, formatting, etc.)
├── index.ts

Components use composables internally; consumers can also import them directly.

Tailwind Integration

  • tailwind.config.ts extends PrimeVue theme with custom utilities
  • Library does NOT bundle Tailwind — consumers must include it in their setup
  • Supports portability: teams can apply custom Tailwind themes independently

Build Output

  • ESM modules (primary) + optional CommonJS
  • TypeScript declarations (.d.ts)
  • Sourcemaps for debugging
  • No dependency bundling (peer deps only)

Playground Package Details

Storybook Configuration

  • Addon: Vue 3 builder
  • Global Setup: preview.ts configures:
    • Tailwind CSS
    • PrimeVue theme setup
    • Global styles
  • Stories Location: stories/ directory

Story Structure

Each component gets a .stories.ts file:

// stories/DatePicker.stories.ts
import DatePicker from '../components/DatePicker.vue'

export default {
  component: DatePicker,
  tags: ['autodocs'],
}

export const Default = {}
export const WithCustomTheme = { args: { /* ... */ } }

Stories serve triple duty:

  1. Interactive documentation for developers
  2. Visual regression baseline
  3. Live testing environment during dev

Preview Configuration

preview.ts sets up:

  • Tailwind CSS
  • PrimeVue initialization
  • Global CSS imports
  • Example theme configuration

Development Workflow

Scripts

Root-level (bun commands):

{
  "dev": "bun -r --cwd packages/playground dev",
  "build": "bun -r --cwd packages/library build && bun -r --cwd packages/playground build",
  "lint": "eslint packages/*/src",
  "type-check": "vue-tsc --build",
  "test": "bun -r --cwd packages/library test:unit"
}

Library scripts:

  • bun dev — (unused for lib, optional for local testing)
  • bun build — Vite library build
  • bun test:unit — Vitest

Playground scripts:

  • bun dev — Start Storybook dev server (port 6006)
  • bun build — Build static Storybook site

Developer Experience

  1. Start playground: bun dev (root) → Storybook on localhost:6006
  2. Edit component: Modify packages/library/src/components/DatePicker/DatePicker.vue
  3. See update: Playground hot-reloads via Storybook
  4. View story: Open stories/DatePicker.stories.ts to add/update examples
  5. Test: Run bun test in library package

Hot Reload

  • Library changes trigger Storybook rebuild
  • Playground imports @nychthemeron/library from source (no build step during dev)

Testing Strategy

Unit Tests

  • Location: packages/library/__tests__/
  • Framework: Vitest + Vue Test Utils
  • Coverage: Component logic, composables, edge cases
  • Command: bun test (from library or root)

Visual Documentation

  • Storybook stories serve as visual baseline
  • Can be extended with snapshot testing if needed

Type Safety

  • vue-tsc --build runs across monorepo
  • CI/local checks ensure no type errors

Build & Deployment

Library Build

  • Output: packages/library/dist/
  • Formats: ESM (primary) + optional CommonJS
  • Declarations: Full TypeScript support
  • Size: Optimized with tree-shaking enabled

Playground Build

  • Output: packages/playground/storybook-static/
  • Deploy: Can be served on internal server, wiki, or documentation site
  • Audience: Internal team, stakeholders, designers

Internal Distribution

No npm publishing. Teams use library by:

  • Cloning/pulling monorepo
  • Installing dependencies: bun install
  • Importing components from @nychthemeron/library

Dependencies

Library Package

Peer Dependencies:

  • vue@^3.5.0
  • primevue@^18.0.0 (or latest)

Dev Dependencies: (shared from root)

  • TypeScript, Vite, ESLint, Prettier

Playground Package

Dependencies:

  • @nychthemeron/library (local workspace package)
  • primevue
  • vue

Dev Dependencies:

  • Storybook (@storybook/vue3)
  • Vite, TypeScript

Success Criteria

  • Monorepo structure set up with bun workspaces
  • Library builds to dist/ with exports
  • Storybook starts with bun dev and hot-reloads on library changes
  • Components use PrimeVue + Tailwind CSS
  • Composables (e.g., useDate) are accessible
  • TypeScript declarations present and correct
  • Unit tests run and pass
  • Shared config (ESLint, Prettier, tsconfig) enforced across packages

Next Steps

  1. Restructure project into monorepo layout
  2. Set up bun workspaces in root package.json
  3. Create library package with Vite lib config
  4. Create playground package with Storybook
  5. Add shared configurations
  6. Implement first component (e.g., Button or DatePicker)
  7. Create corresponding Storybook stories
  8. Test hot-reload workflow