I rebuilt the shared field-component stylesheet that every settings panel in PostX depends on, because the 2019-era monolithic system was blocking new feature work. The core stylesheet shrank from 6,262 lines to 2,529 lines by splitting it into 19 focused files - one per component. The work was self-proposed, executed solo across ~60 commits, completed September 2025, and left each field type independently editable - with affected build assets 20-30% smaller once the change was measured in isolation.
| Problem | A single 2019-era stylesheet controlled every UI field (toggles, color pickers, dropdowns, etc.) across the whole plugin. Editing one field type risked breaking others. |
| Who was affected | Every developer touching any block's settings panel - 13+ files depended on this one system |
| What I did | Proposed and solo-executed a component-by-component rebuild, extracting each field's styles into its own file |
| Outcome | Core stylesheet shrank 60% (6,262 → 2,529 lines), split across 19 independently editable files |
| Bundle impact | Affected assets 20-30% smaller, measured in isolation - an expected cost that didn't materialise |
| Developer experience | 19 independently editable files replaced one shared blast radius across 13+ dependents |
| Timeline | Completed September 2025 |
| Team | Solo |
PostX is a WordPress plugin for building news sites, blogs, and magazines using Gutenberg blocks - post grids, sliders, lists, and more. Every one of those blocks has a settings panel, and every settings panel is built from the same small set of shared field components: toggles, dropdowns, color pickers, typography controls, spacing sliders.
Those components dated back to the plugin's original 2019 codebase. Over six years, their styling logic had all been funneled into one file. By the time I looked at it, that one file controlled the appearance of every field type used across the entire product.
That's a fragile setup. Change a toggle's padding to fix one block, and you risk shifting a toggle somewhere else you didn't even open. I ran into this constraint while working on other features - it was actively slowing things down, not just a theoretical code smell.
I wasn't assigned this. I proposed it, because the shared component system had become a blocker for the feature work I was actually supposed to be doing. Fixing the constraint directly - rather than working around it again - seemed like the higher-leverage move, even though it meant putting other work down for a stretch.
The full decision-making story is in the self-proposed engineering initiative case study →.
Option A - Patch around it. Keep adding to the monolithic file, be extra careful with regression testing each time. Fast short-term, but it doesn't remove the underlying risk, and the file only keeps growing.
Option B - Adopt an existing design-system library. Would have saved build time, but PostX's field components are tightly coupled to WordPress's Gutenberg editor APIs. No strong candidate fit that constraint.
Option C - Extract each component into its own file, one at a time. More work upfront, but it lets each component be understood, tested, and changed in isolation going forward.
I picked Option C because it directly addressed the root cause - a shared blast radius - rather than managing around it.
Over roughly 60 commits across two weeks in June–July 2025, I went through the shared component library one field type at a time: Toggle, Tab, Label, Range, Select, Dimension, Typography, Color, Multi-select, Accordion, and more. For each one, I pulled its styling out of the shared file and gave it its own dedicated partial.
The work paused for about two months while I was reassigned to another project, then picked back up in September 2025 to finish the plan - extending the same approach into new controls (icons, border and alignment settings) as the plugin moved toward its next major version. I've treated this as one continuous initiative rather than two, because the September work was a direct continuation of the same plan, not a new decision.
I kept the working branch in sync with the main codebase throughout, rather than letting it drift and risking a difficult merge at the end.
The clearest number: the core stylesheet (editor.scss) shrank from 6,262 lines to 2,529 lines - a 60% reduction - with that logic redistributed into 19 dedicated component files under a new editor_styles/ folder.
Folder structure - before vs. after
Before: every field's styles lived inside one file.
reactjs/src/helper/
├── editor.scss ← 6,262 lines, every field type mixed together
└── fields/
├── Toggle.js
├── Select.js
├── Range.js
├── Color.js
├── Typography.js
├── Dimension.js
└── ... (component logic only, no dedicated styles)
After: each field owns its own stylesheet, imported into a much smaller editor.scss.
reactjs/src/helper/
├── editor.scss ← 2,529 lines, mostly @imports + shared rules
├── fields/
│ ├── Toggle.js
│ ├── Select.js
│ ├── Range.js
│ ├── Color.js
│ ├── Typography.js
│ ├── Dimension.js
│ └── ... (component logic - unchanged)
└── editor_styles/ ← new folder, one file per field
├── _toggle.scss (54 lines)
├── _select.scss (303 lines)
├── _range.scss (226 lines)
├── _color.scss (274 lines)
├── _color2.scss (138 lines)
├── _typography.scss (447 lines)
├── _dimension.scss (101 lines)
├── _accordion.scss (119 lines)
├── _alignment.scss (79 lines)
├── _icon.scss (139 lines)
├── _label.scss (21 lines)
├── _layout2.scss (104 lines)
├── _linkButton.scss (102 lines)
├── _number.scss (24 lines)
├── _radioImage.scss (55 lines)
├── _rowLayout.scss (78 lines)
├── _section.scss (38 lines)
├── _tags.scss (54 lines)
└── _divider.scss (18 lines)
A representative slice of the ~60-commit sequence, oldest to newest:
77d957187 feat: added wp js linter and formatter deps (May 26)
7ffa69d75 refactor: redesign toggle component (Jun 30)
343715883 refactor: redesign range component (Jul 1)
0681dafae refactor: redesign select component (Jul 2)
9ba5e1770 refactor: multi select component (Jul 2)
9ab2c3e6e refactor: redesign dimension component (Jul 3)
53fde65a2 refactor: redesign color component (Jul 3)
e43969ee4 refactor: redesign typography popup (Jul 6)
f6f37589d refactor: redesign typo field size (Jul 6)
6b6d0eec1 refactor: redesign accordion tabs (Jul 7)
c20fb0dfb refactor: change split scss files (Jul 8)
b7b1c3aee refactor: redesign editor panel sidebar (Jul 8)
...
943d70464 fix: alignment icons (Sep 2)
f570df086 feat: added border position icon (Sep 2)
91fdcd0e5 feat: added border radius position icon (Sep 3)
deac0f96e refactor: improve accordion section styling (Sep 4)
One component per commit. The naming convention - refactor: redesign [component] - makes the series easy to follow and easy to bisect if anything went wrong.
The cost I expected to pay
Splitting one file into 19 generally means more per-file overhead and a larger total bundle. I expected that, and I said so before starting rather than discovering it after shipping - the alternative, keeping everything in one file to minimize size, was the same fragility that caused the problem in the first place.
It didn't turn out that way. My first before/after build comparison did show growth, but the commit range I measured across also added new image assets, which inflated the "after" side independently of the CSS work. Re-measured in isolation, affected assets came in 20-30% smaller - extracting each component surfaced duplicated and dead rules that had been invisible inside a 6,262-line file.
The measurement, what went wrong with the first one, and the developer-experience gains are in the bundle size case study →.
PostX had no automated test suite. The system I was refactoring had 13+ dependent files. I managed that risk through careful, component-by-component commits and manual UI verification - but that's a substitute for tests, not equivalent to them.
The full treatment of this is in the refactoring without a test suite case study →.
What problem did this case study solve?
A single legacy stylesheet controlled the appearance of every UI field (toggles, dropdowns, color pickers, etc.) used across a WordPress plugin's settings panels, making any change risky and slowing down feature work.
Did this improve performance?
Measured in isolation, affected build assets came in 20-30% smaller - extracting each component removed duplicated and dead rules. I had expected the opposite, and an early comparison appeared to confirm growth before I found it was confounded by unrelated image assets. The full measurement is in the bundle size case study →.
How did you manage regression risk with no test suite?
Component-by-component commits, continuous branch sync with main, and manual UI verification after each extraction. It worked - but I'd write test coverage for shared components before starting next time. Full detail in the refactoring without a test suite case study →.
Part of the PostX frontend refactoring case study series →