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/libraryand 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.tsextends 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.tsconfigures:- 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:
- Interactive documentation for developers
- Visual regression baseline
- 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 buildbun test:unit— Vitest
Playground scripts:
bun dev— Start Storybook dev server (port 6006)bun build— Build static Storybook site
Developer Experience
- Start playground:
bun dev(root) → Storybook onlocalhost:6006 - Edit component: Modify
packages/library/src/components/DatePicker/DatePicker.vue - See update: Playground hot-reloads via Storybook
- View story: Open
stories/DatePicker.stories.tsto add/update examples - Test: Run
bun testin library package
Hot Reload
- Library changes trigger Storybook rebuild
- Playground imports
@nychthemeron/libraryfrom 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 --buildruns 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.0primevue@^18.0.0(or latest)
Dev Dependencies: (shared from root)
- TypeScript, Vite, ESLint, Prettier
Playground Package
Dependencies:
@nychthemeron/library(local workspace package)primevuevue
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 devand 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
- Restructure project into monorepo layout
- Set up bun workspaces in root
package.json - Create library package with Vite lib config
- Create playground package with Storybook
- Add shared configurations
- Implement first component (e.g., Button or DatePicker)
- Create corresponding Storybook stories
- Test hot-reload workflow