# Library with Playground Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Transform nychthemeron into a monorepo with a Vue component library (with PrimeVue + Tailwind) and interactive Storybook playground. **Architecture:** Bun workspaces manage two independent packages — library (builds to ESM) and playground (Storybook dev server and static build). Shared configs at root level. **Tech Stack:** Vue 3, PrimeVue, Tailwind CSS, Vite, Storybook, Vitest, TypeScript, Bun workspaces --- ### Task 1: Create monorepo directory structure **Files:** - Create: `packages/library/` directory - Create: `packages/playground/` directory - [ ] **Step 1: Create packages directories** ```bash mkdir -p packages/library/src/{components,composables} mkdir -p packages/library/__tests__ mkdir -p packages/playground/.storybook mkdir -p packages/playground/stories ``` - [ ] **Step 2: Verify structure** ```bash ls -la packages/ # Expected output shows: library/ and playground/ directories ``` --- ### Task 2: Move existing source to library package **Files:** - Move: `src/` → `packages/library/src/` - Delete: `vite.config.ts`, `vitest.config.ts`, `index.html` (will recreate in packages) - [ ] **Step 1: Move src directory** ```bash mv src packages/library/src ``` - [ ] **Step 2: Verify move** ```bash ls packages/library/src/ # Expected: App.vue, main.ts, __tests__/ ``` - [ ] **Step 3: Delete old root-level config files** ```bash rm vite.config.ts vitest.config.ts index.html ``` --- ### Task 3: Update root package.json for monorepo **Files:** - Modify: `package.json` - [ ] **Step 1: Add workspaces and update root config** Replace the entire `package.json` with: ```json { "name": "nychthemeron", "version": "0.0.0", "private": true, "type": "module", "workspaces": [ "packages/*" ], "scripts": { "dev": "bun -r --cwd packages/playground dev", "build": "bun -r --cwd packages/library build && bun -r --cwd packages/playground build", "preview": "bun -r --cwd packages/playground preview", "type-check": "vue-tsc --build", "lint": "eslint packages/*/src --fix", "format": "prettier --write --experimental-cli packages/*/src", "test": "bun -r --cwd packages/library test:unit" }, "devDependencies": { "@tsconfig/node24": "^24.0.4", "@types/jsdom": "^28.0.1", "@types/node": "^24.12.2", "@vitejs/plugin-vue": "^6.0.6", "@vitest/eslint-plugin": "^1.6.16", "@vue/eslint-config-typescript": "^14.7.0", "@vue/test-utils": "^2.4.6", "@vue/tsconfig": "^0.9.1", "eslint": "^10.2.1", "eslint-config-prettier": "^10.1.8", "eslint-plugin-oxlint": "~1.60.0", "eslint-plugin-vue": "~10.8.0", "jiti": "^2.6.1", "jsdom": "^29.0.2", "npm-run-all2": "^8.0.4", "oxlint": "~1.60.0", "prettier": "3.8.3", "typescript": "~6.0.0", "vite": "^8.0.8", "vite-plugin-vue-devtools": "^8.1.1", "vitest": "^4.1.4", "vue": "^3.5.32", "vue-tsc": "^3.2.6" }, "engines": { "node": "^20.19.0 || >=22.12.0" } } ``` - [ ] **Step 2: Install dependencies for new workspace structure** ```bash bun install ``` Expected output: Bun detects workspaces and creates symlinks in each `packages/*/node_modules` --- ### Task 4: Create library package.json **Files:** - Create: `packages/library/package.json` - [ ] **Step 1: Create library package config** ```json { "name": "@nychthemeron/library", "version": "0.1.0", "type": "module", "exports": { ".": { "import": "./dist/index.js" } }, "files": [ "dist" ], "scripts": { "build": "vite build", "test:unit": "vitest" }, "peerDependencies": { "vue": "^3.5.0", "primevue": "^18.0.0" }, "devDependencies": { "@vitest/coverage-v8": "^2.0.0", "@vue/test-utils": "^2.4.6" } } ``` Write this to `packages/library/package.json` - [ ] **Step 2: Verify file exists** ```bash cat packages/library/package.json | grep '"name"' # Expected: "@nychthemeron/library" ``` --- ### Task 5: Create library tsconfig.json **Files:** - Create: `packages/library/tsconfig.json` - [ ] **Step 1: Create library TypeScript config** ```json { "extends": "../../tsconfig.json", "compilerOptions": { "outDir": "./dist", "declaration": true, "declarationMap": true, "emitDeclarationOnly": false }, "include": [ "src/**/*.ts", "src/**/*.vue" ], "exclude": [ "dist", "**/*.spec.ts" ] } ``` Write this to `packages/library/tsconfig.json` --- ### Task 6: Create library vite.config.ts **Files:** - Create: `packages/library/vite.config.ts` - [ ] **Step 1: Create Vite library config** ```typescript import { fileURLToPath } from 'node:url' import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' export default defineConfig({ plugins: [vue()], build: { lib: { entry: fileURLToPath(new URL('./src/index.ts', import.meta.url)), name: 'NychthemeronLibrary', formats: ['es'], fileName: () => 'index.js', }, rollupOptions: { external: ['vue', 'primevue'], output: { globals: { vue: 'Vue', primevue: 'PrimeVue', }, }, }, }, }) ``` Write this to `packages/library/vite.config.ts` --- ### Task 7: Create library vitest.config.ts **Files:** - Create: `packages/library/vitest.config.ts` - [ ] **Step 1: Create Vitest config** ```typescript import { defineConfig } from 'vitest/config' import vue from '@vitejs/plugin-vue' export default defineConfig({ plugins: [vue()], test: { globals: true, environment: 'jsdom', include: ['**/*.spec.ts'], }, }) ``` Write this to `packages/library/vitest.config.ts` --- ### Task 8: Create library export structure **Files:** - Create: `packages/library/src/components/index.ts` - Create: `packages/library/src/composables/index.ts` - Modify: `packages/library/src/index.ts` - [ ] **Step 1: Create components index (empty for now)** ```typescript // Re-export all components here as they're added // export { default as Button } from './Button/Button.vue' // export { default as DatePicker } from './DatePicker/DatePicker.vue' ``` Write this to `packages/library/src/components/index.ts` - [ ] **Step 2: Create composables index (empty for now)** ```typescript // Re-export all composables here as they're added // export { useDate } from './useDate' ``` Write this to `packages/library/src/composables/index.ts` - [ ] **Step 3: Create root library entry point** ```typescript export * from './components' export * from './composables' ``` Write this to `packages/library/src/index.ts` - [ ] **Step 4: Remove old App.vue and main.ts from library (they were for the app)** ```bash rm packages/library/src/App.vue packages/library/src/main.ts ``` --- ### Task 9: Create playground package.json **Files:** - Create: `packages/playground/package.json` - [ ] **Step 1: Create playground package config** ```json { "name": "@nychthemeron/playground", "version": "0.1.0", "type": "module", "scripts": { "dev": "storybook dev -p 6006", "build": "storybook build", "preview": "npx vite preview" }, "dependencies": { "@nychthemeron/library": "workspace:*", "primevue": "^18.0.0", "vue": "^3.5.32" }, "devDependencies": { "@storybook/addon-essentials": "^8.0.0", "@storybook/addon-interactions": "^8.0.0", "@storybook/addon-links": "^8.0.0", "@storybook/blocks": "^8.0.0", "@storybook/vue3": "^8.0.0", "@storybook/vue3-vite": "^8.0.0", "storybook": "^8.0.0", "tailwindcss": "^3.4.0", "autoprefixer": "^10.4.0", "postcss": "^8.4.0", "typescript": "~6.0.0", "vue": "^3.5.32" } } ``` Write this to `packages/playground/package.json` --- ### Task 10: Create playground tsconfig.json **Files:** - Create: `packages/playground/tsconfig.json` - [ ] **Step 1: Create playground TypeScript config** ```json { "extends": "../../tsconfig.json", "compilerOptions": { "composite": false, "jsx": "preserve", "lib": [ "dom", "dom.iterable", "esnext" ] }, "include": [ ".storybook/**/*.ts", ".storybook/**/*.tsx", ".storybook/**/*.vue", "stories/**/*.ts", "stories/**/*.tsx", "stories/**/*.vue" ] } ``` Write this to `packages/playground/tsconfig.json` --- ### Task 11: Create playground Tailwind config **Files:** - Create: `packages/playground/tailwind.config.ts` - [ ] **Step 1: Create Tailwind config** ```typescript import type { Config } from 'tailwindcss' export default { content: [ './.storybook/**/*.{ts,tsx,vue}', './stories/**/*.{ts,tsx,vue}', '../library/src/**/*.vue', ], theme: { extend: { colors: { primary: { 50: '#f0f9ff', 500: '#0ea5e9', 900: '#0c2d6b', }, }, }, }, plugins: [], } satisfies Config ``` Write this to `packages/playground/tailwind.config.ts` --- ### Task 12: Create Storybook main config **Files:** - Create: `packages/playground/.storybook/main.ts` - [ ] **Step 1: Create Storybook main configuration** ```typescript import type { StorybookConfig } from '@storybook/vue3-vite' const config: StorybookConfig = { stories: [ '../stories/**/*.stories.ts', ], addons: [ '@storybook/addon-essentials', '@storybook/addon-interactions', '@storybook/addon-links', ], framework: { name: '@storybook/vue3-vite', options: {}, }, core: { disableTelemetry: true, }, } export default config ``` Write this to `packages/playground/.storybook/main.ts` --- ### Task 13: Create Storybook preview config **Files:** - Create: `packages/playground/.storybook/preview.ts` - [ ] **Step 1: Create Storybook preview configuration** ```typescript import type { Preview } from '@storybook/vue3' import 'primevue/resources/themes/lara-light-blue/theme.css' import 'primevue/resources/primevue.min.css' import '../tailwind.css' const preview: Preview = { parameters: { layout: 'centered', docs: { description: { component: 'Component documentation', }, }, }, } export default preview ``` Write this to `packages/playground/.storybook/preview.ts` --- ### Task 14: Create Tailwind CSS entry point **Files:** - Create: `packages/playground/tailwind.css` - [ ] **Step 1: Create Tailwind directives file** ```css @tailwind base; @tailwind components; @tailwind utilities; ``` Write this to `packages/playground/tailwind.css` --- ### Task 15: Create example story **Files:** - Create: `packages/playground/stories/Example.stories.ts` - [ ] **Step 1: Create example story for testing** ```typescript import type { Meta, StoryObj } from '@storybook/vue3' const meta = { title: 'Example/Welcome', parameters: { layout: 'centered', }, tags: ['autodocs'], } satisfies Meta export default meta type Story = StoryObj export const Welcome: Story = { render: () => ({ template: `

Nychthemeron Component Library

Interactive playground for Vue components with PrimeVue + Tailwind

`, }), } ``` Write this to `packages/playground/stories/Example.stories.ts` --- ### Task 16: Install dependencies and verify structure **Files:** - None (verification only) - [ ] **Step 1: Install dependencies for all packages** ```bash bun install ``` Expected: All packages get dependencies installed, workspace links created - [ ] **Step 2: Verify workspace structure** ```bash ls -la packages/library/node_modules/@nychthemeron/library # Expected: symlink to ../.. ls -la packages/playground/node_modules/@nychthemeron/library # Expected: symlink to ../../../library ``` - [ ] **Step 3: Type-check across monorepo** ```bash bun type-check ``` Expected: No TypeScript errors --- ### Task 17: Test dev server startup **Files:** - None (verification only) - [ ] **Step 1: Start Storybook playground** ```bash bun dev ``` Expected output: ``` Storybook 8.x started Local: http://localhost:6006 ``` - [ ] **Step 2: Verify Storybook loads in browser** Open `http://localhost:6006` in a browser. Expected: Storybook UI loads with "Example/Welcome" story visible showing the welcome message. - [ ] **Step 3: Verify story renders correctly** In Storybook, click "Example/Welcome" → verify the welcome message displays with correct styling. Expected: - Title: "Nychthemeron Component Library" (blue, large) - Subtitle: "Interactive playground..." (gray, smaller) - [ ] **Step 4: Stop dev server** ```bash # Press Ctrl+C in terminal ``` --- ### Task 18: Test library build **Files:** - None (verification only) - [ ] **Step 1: Build library** ```bash bun -r --cwd packages/library build ``` Expected output: ``` ✓ 123 modules transformed dist/index.js 1.23 kb dist/index.d.ts 0.5 kb ``` - [ ] **Step 2: Verify dist files exist** ```bash ls packages/library/dist/ ``` Expected: ``` index.d.ts index.js ``` - [ ] **Step 3: Verify exports are correct** ```bash head -20 packages/library/dist/index.js ``` Expected: JavaScript code with ES module exports (starts with `import` or defines exports) --- ### Task 19: Initialize git for monorepo **Files:** - None (git initialization only) - [ ] **Step 1: Initialize git repo (if not already)** ```bash git init ``` - [ ] **Step 2: Add gitignore entries for workspace** Append to `.gitignore`: ``` packages/*/dist packages/*/node_modules packages/*/.storybook-static ``` - [ ] **Step 3: Create initial commit (SKIP - user requested no commits)** Note: Commit skipped per user request --- ## Self-Review **Spec coverage:** - ✅ Monorepo structure (Task 1) - ✅ Bun workspaces setup (Tasks 2-3) - ✅ Library package creation (Tasks 4-8) - ✅ Composables structure (Task 8) - ✅ Playground/Storybook setup (Tasks 9-15) - ✅ Tailwind integration (Tasks 11, 14) - ✅ PrimeVue initialization (Task 13) - ✅ Dev workflow verification (Task 17) - ✅ Build verification (Task 18) - ✅ Git initialization (Task 19) **Placeholder scan:** No TBDs, "fill in later", incomplete steps. All code blocks are complete and exact. **Type consistency:** Package names consistent (`@nychthemeron/library`, `@nychthemeron/playground`). All import paths and config keys match across tasks. **Scope:** Plan produces working, testable monorepo. Library builds to `dist/`, Storybook starts and loads stories. Next phase (adding components) is separate.