Back to projects

Case Study · 01

Composable Commerce at Scale:
A Six-Year Platform Transformation

How a Magento 1 monolith carrying a decade of technical debt became a composable, multi-team platform, built sprint by sprint, and designed to be extended rather than rebuilt.

The Starting Point

The e-commerce platform had been running since 2009 on Magento 1. Over nearly a decade, it had grown from a manageable shop into a system carrying the weight of ten years of accumulated technical debt — and a product catalogue that had expanded from 30,000 to over 70,000 SKUs.

By 2019, the platform had become a bottleneck. New features took weeks to develop, deployments were slow and risky, and performance under load was a constant concern. The business was growing. The platform wasn't.

Something had to change.

The Strategic Decision: MVP over Full Rebuild

The temptation in a situation like this is to rebuild everything. Start fresh, do it right, migrate the entire feature set before going live.

We made a different call.

Instead of a full rebuild, we built a minimal but highly performant Spryker-based platform with a deliberately reduced feature set. The goal wasn't completeness, it was speed and stability. Spryker's event-driven architecture and Redis-cached frontend data gave us a platform that was significantly faster than what we were replacing, even with fewer features.

The new platform went live in late 2019. It wasn't the full shop. It was the foundation.

Scaling Through Agile Delivery

From that foundation, we built sprint by sprint. Each iteration added features the old platform had: additional product media, documentation, assembly guides, and product videos. The team was working in Scrum, which meant we could respond to user behaviour quickly and adjust priorities based on what actually mattered to customers.

The team grew as the platform grew. What started as a team of 14–15 people eventually scaled to over 20, split into three squads, then restructured into two. The architectural decisions made in the MVP phase had to hold up under that organisational scale — and largely they did.

Four Weeks, Two Sprints, Corona

In early 2020, the world changed. Physical retail closed overnight, and businesses scrambled to adapt.

Within two sprints (four weeks) we built and shipped a Click & Collect system that allowed customers to order online and pick up directly from the warehouse. No third-party solution, no compromise on the existing architecture. Just focused engineering on a real business problem under real time pressure.

It was the clearest demonstration of what the new platform made possible. On a tightly coupled, monolithic architecture, a fast-tracked checkout mutation like that would have posed an unpredictable deployment risk and taken months.

Leading Across Team Boundaries: The Stack Transition

As the platform evolved, our organisational structure adapted with it. A separate, cross-functional 12-person team — comprising UX/UI designers, frontend and backend developers, and DevOps/infrastructure experts — began navigating a major architectural shift from Spryker Yves to Next.js.

Technical leadership in this context meant supporting this autonomous team through their initial MVP release without having formal authority over them. The goal was to help them navigate complex migration challenges that mirrored what we had already worked through, ensuring their independent infrastructure and delivery models remained aligned with our core commerce backend.

The GraphQL Middleware Layer

In the second half of 2024, we made the next significant architectural move to unlock this multi-team ecosystem.

The trigger was the Customer Loyalty Programme — a new system that needed to live entirely outside of our commerce core. Rather than building point-to-point integrations into an architecture that had previously communicated primarily with a single CRM/ERP system, we designed a GraphQL API layer with strong, explicit contracts as a separate deployment target.

The contracts themselves were developed collaboratively, working directly with the Flutter mobile app team and the Next.js frontend team from the start. This consumer-driven approach meant the API reflected real usage patterns rather than assumptions, and both teams could begin integrating against stable interfaces without waiting for the core backend to be fully complete.

The result was a decoupled layer that allowed multiple teams to ship independently against a shared contract, without requiring modifications to core backend logic every time a new consumer came online.

What I'd Do Differently

The early implementations of our Redis, Storyblok, and Spryker Glue clients were too pragmatic. They got the job done in the short term, but because we didn't enforce strict interface abstractions from day one, these third-party SDKs bled directly into our business logic. This shortcut required significant, painful refactoring waves later on — friction that could have been avoided entirely.

The lesson isn't that speed is wrong. The MVP approach was the right call. The lesson is that foundational clients and integration layers deserve strict encapsulation from the start. The cost of proper upfront boundaries is almost always lower than the cost of untangling dependencies after the rest of the ecosystem has been built on top of them.

Key Takeaways

Ten years of technical debt don't disappear overnight. But the right architectural foundation, built pragmatically, scaled deliberately, and evolved strategically, can turn a platform from a bottleneck into a business accelerator.

The composable approach worked not because it was technically elegant, but because it was designed to evolve. Every major capability added since 2019 — Click & Collect, the GraphQL middleware, the mobile app — was possible because the foundation was built to be extended, not rebuilt.

That's the difference between feature delivery and platform thinking.