WowInvoice: Frontend Engineering for a WooCommerce PDF Invoice Plugin - 3 Case Studies
3 case studies from WowInvoice, a WooCommerce PDF invoice and packing slip plugin: credit notes that show only what was refunded, one partial-payment layer for four deposit plugins, and a live preview that opens the setting you click.
Linking Shared Template Parts to a Live Preview's Settings Panel
WowInvoice's live preview opens the matching setting when you click part of a document. I extended that to shared template parts by switching them from a callback prop to forwarded refs, and lifted the settings accordion's state so a click in the preview could open it.
Extending One Partial-Payment Layer to Four WooCommerce Deposit Plugins
WowInvoice invoices had to show deposits and balances for four WooCommerce deposit plugins that each store them differently. I read each plugin's source, added three providers to an existing layer, and made every invoice resolve to the parent order.
WooCommerce Credit Notes That Show What Was Actually Refunded
WowInvoice's credit notes printed the whole order instead of the refund. I chose a one-class first fix over a multi-week rebuild, classified every refund into one of ten cases, and made the totals always reconcile to the refunded amount.
4 case studies from the WowShipping WooCommerce shipping plugin's frontend: a Gutenberg component migration that didn't survive a branch merge, a hand-built drag-and-drop interaction, a naming-convention overhaul, and a domain-vocabulary rename.
How I renamed WowShipping's primary UI concept from "shipping rules" to "shipping methods" across 45 files - and what deliberately stayed unrenamed underneath.
Five commits, one calendar week - converting an entire WooCommerce plugin's component library, page folders, and context files from PascalCase to kebab-case, then regrouping local components into their own subfolder.
Reordering shipping methods needed drag-and-drop. I built it on the raw HTML5 Drag and Drop API - including the ref-counter fix for the classic dragenter/dragleave flicker bug - with no new dependency.
The Select Component Trade-off: Migrating to Gutenberg's SelectControl
I migrated a shared Select wrapper to Gutenberg's native SelectControl behind a preserved prop API. Tracing the commit history later, I found the migration didn't survive the next branch merge - and nothing broke anyway.
AI Recommendation Builder That Had to Keep Up With Its Own Rule Book - 3 Case Studies
The admin builder for a WooCommerce product-recommendations plugin - a visual placement tool where the state model, the rule vocabulary, and two near-identical components all had to grow without breaking each other. Three linked case studies.
A WooCommerce recommendation builder needed several independent lists per placement, not one - why I kept the nested state shape and adopted Immer instead of flattening it.
Turning a Growing Rule Vocabulary Into Data Instead of Code
A recommendation builder filter vocabulary kept growing - category, price, browsing behavior, purchase history, each with its own valid operators. Why I moved that vocabulary into data instead of component logic.
A recommendation builder needed a filter-rule row and a sort-rule row that looked almost identical - why we built them as siblings instead of one shared abstraction, and how I kept them from drifting apart.
A Shared Component Architecture in a Monorepo - 4 Case Studies
A solo, year-long build of a 44-component Vue library shared between two independently built apps inside a WordPress booking plugin - four linked case studies covering API boundaries, state, resilient input handling, and codebase structure.
Structuring a Large Frontend Codebase for Maintainability at Scale
Two independently-built Vue apps and a webpack-built Gutenberg block shared one component library through a consistent alias system and a per-app Tailwind purge - except in the one place plain CSS won.
Centralizing State Management Across a Multi-App Architecture
Migrating 21 Pinia stores across two independently-built Vue apps to the Composition API, and routing their data-shaping logic through one shared model layer instead of duplicating it in each store.
Designing Component APIs That Scale Across Two Applications
PreBook ships two independently-built Vue apps against one shared component library with no package boundary, so every reusable component forces the same question - what generalizes, and what stays local to the app that needs it.
A self-proposed, solo-executed refactor of a WordPress Gutenberg plugin used by 40,000+ users - five linked case studies covering the technical execution, the decision, the trade-offs, and the risk.
JavaScript Linting & Formatting Setup for a WordPress Gutenberg Plugin
Adding ESLint and a formatter to a Gutenberg block plugin codebase - the groundwork that made the CSS refactor safer, and the paired initiative behind it.
Bundle Size After a CSS Split: Measuring What Actually Changed
I expected splitting one stylesheet into 19 files to cost bundle size. The first measurement said it grew - until I isolated unrelated image assets and re-measured: a 20-30% reduction.
How I refactored 13+ dependent files with no automated tests - what I verified manually, what the risks were, and what I would do differently next time.