Dhaka, Bangladesh
Case Studies

A Shared Component Architecture in a Monorepo - 4 Case Studies

Cover image for the case study "A Shared Component Architecture in a Monorepo - 4 Case Studies"
Solo, over about a year, one 44-component library shared by two apps - documented across four linked case studies.
I built and maintained the shared component library behind PreBook, a WordPress appointment-booking plugin, solo across roughly a year - December 2023 to November 2024. 44 Vue components, 3,639 lines, serve two independently built apps - an admin app and a customer-facing booking frontend - through a shared alias, with no published package between them. Four linked case studies cover API design, state management, resilient input handling, and codebase structure.
PreBook ships three build targets - admin, frontend, and a Gutenberg block - that all needed the same primitives, so I built one component library and aliased it into each.
PreBook is a WordPress plugin that adds appointment booking to a site - staff, services, availability, and the booking flow itself. It ships two Vue 3 single-page apps - an admin app and a customer-facing frontend - plus a third build target, a Gutenberg block, that embeds booking into the WordPress block editor. Both apps needed the same primitives - selects, inputs, modals, date and time pickers, menus - and building each twice risked every fix and design change drifting out of sync. I built a single src/components/ library instead: 44 components, 3,639 lines, imported through one barrel file and wired into both apps' build configs via an identical @components alias rather than a published npm package. I authored essentially all of it solo, across 287 commits, over roughly a year. The four case studies below cover the decisions behind it: where to draw the reuse boundary, how to keep state thin, how to make an input component survive real-world data, and how to keep three build targets pointed at one source of truth.
Four case studies, one library viewed from four angles: the API boundary, the state layer, the input components, and the codebase structure.
The boundary-drawing case study. Where reuse paid off, and where it didn't - Select's fifteen-commit arc against a moving spec, and why Menu's wrapper stayed shared while MenuItem stayed app-local. The state case study. Seventeen admin stores and four frontend stores migrated to Composition-API defineStore form, kept thin by routing through one shared @model/@utils layer instead of duplicating logic per store. The input-handling case study. InputPrice's eighteen-commit fight to keep the cursor stable while reformatting a number on every keystroke across four ambiguous locale separator conventions - and why the bug resurfaced even after an optimization pass. The structure case study. How one path-alias convention and matching Tailwind purge scanning kept three build targets - two Vite apps and a webpack Gutenberg block - pointed at one component source, plus a counter-example where utility classes were deliberately moved back to plain CSS. This series is also available as a condensed cross-post on Dev.to.
The background questions this pillar page answers: what PreBook is, who built the library, what shared without a package means, and what the measurable outcome was.
A WordPress plugin that adds appointment booking to a site - staff, services, and availability on the admin side, booking on the customer-facing side. The two apps aren't separate consumers pulling a versioned dependency - they're two Vite builds aliasing @components to the same folder on disk, so a change is live in both apps' next build with nothing to publish. 44 components, 3,639 lines, serve both apps from one source, with 17 admin stores and 4 frontend stores routed through a shared data layer instead of each app re-implementing its own.
On this page
Quick answer
The initiative
The case studies
Designing Component APIs That Scale Across Two Applications →
Centralizing State Management Across a Multi-App Architecture →
Engineering Resilient Input Components for Real-World Data →
Structuring a Large Frontend Codebase for Maintainability at Scale →
FAQ
What is PreBook?
What does "shared" mean here if there's no published package?
What was the measurable outcome?