Appliances Online / Winning Group / Project note
The project I started in 2015 and came back to modernise
I joined Winning Group to replace a slow, sprawling jQuery e-commerce frontend. Years later, I returned to help the same platform evolve with Nx, a Storybook migration, Angular upgrades, performance work and a much stronger developer experience.
- Role
- Lead Frontend Engineer
- Period
- 2015–2017 & 2020–present
- Disciplines
- Platform Rewrite · Frontend Architecture · Performance · Developer Experience · Design Systems
- Technologies
- Angular · TypeScript · Nx · Storybook · ESLint · Prettier · Node.js · Webpack · AWS · Bamboo
The brief was under three seconds
When I joined Winning Group in May 2015, the brief was refreshingly direct:
Rebuild the Appliances Online frontend and get its pages loading in under three seconds on both desktop and mobile.
At the time, the browser side of the platform had grown into a large collection of jQuery code attached to a .NET application. There had never been a dedicated frontend engineering practice. Full-stack developers were maintaining the backend and doing their best to keep the increasingly complicated frontend moving as well.
Some JavaScript files had grown to around 4,000 lines.
The problem was not simply that the files were long. Behaviour, presentation and page-specific business rules had become tightly connected. Large parts of the code had turned into spaghetti: a small change could lead you through several unrelated areas of the application before you understood what else it might affect.
The full-stack developers had reached the point where they were actively asking for a dedicated senior frontend developer to take ownership of the problem. They understood the system, but maintaining an increasingly complex frontend alongside the .NET backend was no longer sustainable.
Mobile performance was also becoming impossible to ignore. I was seeing pages take around 13 to 14 seconds to load, weighed down by large HTML responses and global JavaScript and CSS files, without modular loading or tree shaking.
I had been hired as the first dedicated senior frontend developer to change that.
Starting with a mostly blank page
I initially worked on the frontend rewrite by myself, with a junior developer joining me later.
I wasn’t fully aware of it at the time, but those circumstances made me to do the early architecture decisions matter enormously. They gave me a rare opportunity to think, experiment, observe, inpired and create a blank canvas architecture from the ground up.
I was not only writing the next page; I was creating the structure that future developers would inherit.
I introduced Angular, TypeScript, a more modular component-based approach with atomic design and component-scoped styling later. Today, those choices sound fairly ordinary. In 2015, moving a large e-commerce frontend away from page-level jQuery into typed, reusable modules was a significant shift.
Honestly, the hardest part was not choosing the framework. It was deciding where all the boundaries belonged and how they should communicate with one another.
What was genuinely reusable? What was specific to a customer journey? What did the business think about removing one thing or introducing another? What would be the best folder structure? How should we break the application into smaller pieces, and what naming conventions should we follow? What should remain controlled by the backend? How could we improve the frontend without stopping a very busy e-commerce platform while replacing its pages one by one with the new system?
We rebuilt the website progressively, page by page.
Each rewritten page had to preserve the existing behaviour and design while improving scalability and maintainability and meeting the page-loading performance target. The pages moved onto the new architecture while the old and new systems temporarily lived alongside one another.
Every page I rewrote met the under-three-second KPI.
Angular was not solely responsible for that. Performance came from reducing unnecessary JavaScript, modularising the code into chunks with tree shaking, controlling what was loaded above the fold and what did not need to load initially below it, improving rendering behaviour, reviewing third-party code and working carefully across frontend and backend boundaries.
The framework gave us a better way to organise those decisions.
Leaving the company and returning a second time
After a few years, I left Winning Group and moved into consulting roles.
Other frontend engineers continued developing Appliances Online. The platform gained new features, new requirements and new contributors. It became a shared system rather than something shaped only by its original architecture.
I still thought of it as my technical baby.
When I returned to Winning Group in 2020, coming back to Appliances Online felt a little like returning home, but it was also a useful lesson in letting go of your own old decisions.
The application was still recognisable, but years of real product development had changed it. New patterns had appeared. Similar components had been created in different areas. Third-party dependencies had gradually entered the codebase. Some original ideas had survived well, while others no longer matched how Angular or the wider frontend ecosystem had evolved.
That is normal.
Long-lived software does not stay clean simply because its first architecture was sensible. It needs repeated attention as the product, team and technology change.
For me, the second chapter was about helping the platform become one of the first to adopt the latest capabilities in the frontend landscape, building on both the foundation I had established in the first and everything it had become through years of product growth, change and contributions from many other developers.
Migrating to modern Angular APIs
Angular had changed enormously since the platform’s early years.
Newer releases introduced standalone APIs, signals, built-in template control flow, deferred views and a path towards zoneless change detection. These were not merely syntax improvements. Together, they offered a cleaner application model and opportunities to reduce both runtime and mental overhead.
We began adopting the newer patterns gradually.
The newer APIs brought substantial benefits. Standalone architecture reduced unnecessary module ceremony. Signals provided a more explicit way to model reactive state. Built-in control flow made templates clearer, while deferred loading allowed less-important features to stay outside the initial rendering path.
Even with those benefits, we kept asking whether each migration answered at least one practical question:
- Does it improve website performance so our users have a better experience?
- Does it improve developer experience so our engineers enjoy working on the platform?
- Does it remove unnecessary complexity from the codebase?
- Will it make future upgrades easier?
The combined modernisation work produced a major improvement in LCP in our internal measurements.
Just as importantly, the code began to feel current again.
People enjoy working in software that appears intentionally maintained. A modern codebase helps existing developers build features faster, improves the experience of someone joining the team for the first time and makes hiring much easier.
Removing code we no longer needed
Years of development had also left the platform with dependencies that no longer justified their cost.
Some large UI packages were being used for only a small piece of functionality. Other utilities had once been useful but had gradually become replaceable through the framework or smaller internal code.
I reviewed dependencies based on more than bundle size:
- How much of the package were we actually using?
- Was it still actively maintained?
- Did it meet our accessibility requirements?
- Did it fit the design system?
- Would replacing it leave us maintaining something more complicated?
- Was it blocking a framework upgrade?
The goal was never to remove dependencies for the sake of having fewer dependencies. The goal was to understand what each one was costing us.
The same principle applied to our components.
Over time, similar product tiles, navigation elements and other UI patterns had appeared under different names across the website. Some differences were meaningful. Others were simply the result of teams solving similar problems at different times.
I worked closely with the design team to bring genuinely related patterns back together.
That did not mean creating one enormous component with dozens of switches and unrelated business rules. A shared component should still represent one coherent idea.
Variants for size, emphasis or layout can belong together. Entirely different responsibilities should not.
Bringing the shared UI kit to life with Storybook
Nx came later in the platform’s history as more applications and shared libraries were brought into the same workspace.
The important part was not simply having a monorepo. It was making the relationships between applications and shared code easier to see and maintain.
Shared libraries gave us a clearer place for reusable UI and supporting functionality, but they also needed ownership and boundaries. Otherwise, a shared library can become another version of the 4,000-line jQuery file: centralised, but still difficult to reason about.
I created a Storybook workspace for the shared UI components so developers and designers could see what already existed before creating another variation.
We added responsive viewport controls, theme switching and documented component states. Storybook became a workshop where components could be developed and discussed away from the complexity of a complete customer journey.
It did not magically create a design system, but it made the system visible.
Automating the boring things
The development workflow needed modernising too.
The project still carried old TSLint-era configuration that was no longer providing useful feedback. I replaced it with a modern ESLint and Prettier setup, together with shared VS Code settings and Git hooks.
Formatting should be boring.
Developers should not spend code reviews debating spacing, import order or whether someone remembered to run a command manually. Prettier handled formatting, while ESLint focused on the correctness and maintainability rules we had deliberately selected.
Supported fixes ran on save, and Git hooks provided a final local check before code moved further through the workflow.
The aim was not to create the strictest possible setup. It was to create useful feedback quickly enough that developers trusted it rather than searched for ways around it.
We also established a regular Angular and Nx upgrade rhythm. Instead of allowing several years of framework changes to accumulate into another painful migration, upgrades became part of normal platform maintenance.
What survived
I have worked on Appliances Online during two very different periods.
The first was about creating a strong frontend engineering foundation where one did not yet truely exist at that time.
The second was about helping that already established ground foundation which evolved more after years of product growth, changes and contributions from many other developers.
The experience changed how I think about architecture.
A good platform is one you build with care and a great deal of love from the beginning, then maintain with regular housekeeping so it can survive new teams, new requirements and new generations of technology without needing to be demolished every few years.
That is easier said than done. Keeping a platform healthy means working with engineering managers and the CTO on priorities, negotiating with marketing teams over the third-party measurement tools they want to integrate, and collaborating with designers to keep design tokens and the shared UI library aligned across Figma and Storybook without introducing excessive duplicate UI.
It also means showing the wider business why this work has lasting value. Time for platform maintenance is rarely created by good intentions alone; engineers need to explain what it protects, what it enables and why it deserves space alongside visible product work.
The part I value most is not that Appliances Online still resembles what I started building in 2015.
It is that it was able to keep changing.