Skip to main content
Enterprise SaaS / Data Analytics
Fractional Frontend Architect
16 weeks
2025

From Legacy Chaos to Config-Driven Architecture: A Complete Frontend Rewrite

12 copy-pasted chart wrappers, zero reusability, and a 4-person team spending more time fighting the codebase than building features.

Client name withheld under NDA. Industry, scope, and results are accurate.

Share:
75%
Team size reduction (4 → 1-2 devs)
0→40+
Design system components created
100%
Config-driven UI coverage

The Challenge

The platform was a data-intensive dashboard for operations teams — multi-source time-series visualization, frequency analysis, signal playback, and event tracking across thousands of monitored entities. Valuable product, terrible frontend:

  • Built on Create React App. No modern tooling, no build optimization, no code-splitting.
  • Rampant copy-paste. The same interactive chart wrapper existed in 12 different versions. Every new visualization was hand-coded from scratch. Zero reusability.
  • No design system. Colors, spacing, typography varied across every screen. Legends, toolbars, and filter controls were reimplemented for each view with subtly different APIs.
  • No separation of concerns. Data fetching, chart configuration, business logic, and rendering — all tangled together in monolithic components. Some exceeded 800 lines. State management was prop drilling mixed with scattered useEffect chains. No caching, no request cancellation, no per-section loading states.
  • Adding anything was painful. A new data source, chart variant, or dashboard view meant touching dozens of files and manually wiring everything. The 4-person team spent most of their time fighting the codebase, not building features.

The first challenge wasn't technical — it was political. The stakeholders didn't understand what a design system was or why the architecture needed an overhaul instead of just fixing individual bugs. I had to show them, with their own codebase, why patching wasn't going to work.

The Approach

Getting buy-in came first. Before writing any code, I ran workshops with product, design, and engineering. I pulled up the 12 duplicate chart wrappers on screen: "Here's the list. These all do roughly the same thing. This is why features take three weeks instead of three days." I mocked up their own screens running on a config-driven system and showed how a single metadata object could replace hundreds of lines of hand-wired code. I ran the cost math: the current approach required 4 developers to maintain what should take 1-2 with proper architecture. The data won the argument.

Foundation: Vite + design system (4 weeks). Migrated from CRA to Vite for instant HMR, then built the design system from scratch — 40+ components, from primitives (Button, Input, Card, Badge) to domain-specific ones (SeriesLegend, AnnotationToolbar, FilterPanel, CollapsiblePanel). All with consistent TypeScript APIs and full variant support. I established a custom-hooks architecture with strict single-responsibility: one hook per concern (data fetching, chart annotations, threshold visualization, filter state), each composable with the others.

The config-driven data-layer system (6 weeks). This was the architectural core — the idea that the entire visualization UI should be driven by backend metadata, not hardcoded frontend logic:

  • Orchestrator Container — a central component that receives a metadata schema and orchestrates the full page. Which data layers to render, in what order, with which graphs, legends, filters, and features. It manages per-section loading states, cross-layer interactions, and layout composition.
  • Metadata Schema — each data layer (live feeds, frequency analysis, time-series signals, event logs) is defined by a JSON config: enabled/disabled, display title, graph definitions, chart types, legend entries, feature toggles (like unit switching between raw and derived metrics), and filter bindings. The backend owns the schema. The frontend renders whatever the config says.
  • Component Registry — maps config IDs to React components. Adding a new visualization type means registering one component. The orchestrator handles the rest.
  • Specialized chart hooks — a composable suite for the Plotly.js charting: useFetchData (per-section loading states, session caching with 5-min TTL, request cancellation), useAnnotationMarkers (cursor tracking and reference-line overlays), useThresholdBands (configurable threshold regions), useFrequencyOverlays (spectral views), useFilterState (unified filter management across dropdowns, chips, search, checkboxes, radios).
  • Adapter Pattern — transforms raw API responses into the normalized shape each component expects. When the API evolves, only the adapter changes — not 30 components.

Advanced features + handoff (4 weeks). With the architecture in place, the complex features practically built themselves:

  • Signal playback — Web Audio API integrated with the time-domain visualization. Analysts can listen to raw signals alongside the visual waveform. Sample-accurate sync derived from the sample_rate metadata field.
  • Event overlays — zoom-aware colored regions on charts representing system events. A bucketing algorithm caps rendered shapes at 100 for consistent performance, with tooltips and pagination for dense clusters.
  • Smart navigation — detects available data layers per entity and routes users to the most relevant view, eliminating "empty screen" dead ends.

I documented everything with developer guides covering each subsystem, then trained the remaining team on extending the system independently.

Tech Stack

Vite
React 18
TypeScript
Tailwind CSS
Plotly.js
Web Audio API
TanStack Query
Zustand
Custom Design System
Config-Driven Data Layers
Component Registry Pattern
Adapter Pattern
Feature Flags

The Results

This was the most dramatic transformation of any engagement I've done.

Team efficiency:

  • 4 developers → 1-2. The config-driven architecture eliminated manual frontend work for most new features. What used to require building a new dashboard view — wiring charts, legends, filters, data fetching — now requires updating a metadata config.
  • New data-layer views: 2-3 weeks → 1-2 days. Define the config, register any new components, the orchestrator handles the rest.

Architecture:

  • 0 → 40+ design system components — SeriesLegend, AnnotationToolbar, FilterPanel, CollapsiblePanel, ThresholdBands, and more. All typed, documented, variant-aware.
  • 100% config-driven UI. The 12 duplicate chart wrappers became one configurable Plotly.js component.
  • 8 specialized hooks with strict single-responsibility — data fetching, annotations, thresholds, frequency overlays, filters — each composable and independently testable.

Technical depth:

  • Sample-accurate audio playback synced with visual analysis via Web Audio API.
  • Zoom-aware event rendering with intelligent bucketing for consistent performance at any data density.
  • Adapter layer insulating 30+ components from backend API changes.
  • Per-section/per-source loading states with session caching and automatic request cancellation.

Business impact:

  • Reduced team requirement translated directly to cost savings — budget freed for backend and data engineering hires.
  • New data sources and visualization types deploy through config changes, not frontend sprints.
  • Comprehensive docs mean any new engineer can extend the system independently.

The CTO's words: "From total chaos to the cleanest codebase in the company."

More Case Studies

Get started

Ready to Level Up Your Product?

I take on a handful of companies at a time. Reach out to discuss your challenges and see if there's a fit.

Send a Message