Living With a Hard Dependency
Joran Quinten works at Jumbo Tech Campus (JTC), the digital arm of Dutch grocery chain Jumbo Supermarkten. The department houses over 350 developers working in agile teams across a range of e-commerce and grocery applications. At JTC, 70% of each team's work is dedicated to primary business objectives; the remaining 30% is free for any work that benefits the wider organization. That split matters when it comes to maintaining shared tooling.
JTC relies on an internally built design system and component library called Kompas ("Compass" in Dutch), rendered with Vue. Kompas is a hard dependency for virtually all applications in the landscape — that uniformity is deliberate, but it concentrates risk. Because no dedicated team owns Kompas, the front-end community contributes directly: any developer can add components, extend existing ones, or sync them with the latest designs, provided the work passes peer review. A team can typically make a change in Kompas, have it reviewed both inside and outside its own team, publish a release, and consume that release in its own application within a single sprint.
That velocity depends on automation for the repetitive parts — linting, formatting, quality checks, visual comparisons, and publishing. Kompas ships multiple minor releases and patches weekly, relying on semantic versioning to keep the applications that consume it up to date with confidence. For larger initiatives, JTC spins up voluntary "front-end chapters" that coordinate work across teams, with members executing in their 30% free time.
This setup worked well while Vue was at version 2. Kompas was built on Vue 2, and the entire application landscape followed. Then Vue 3 shipped as a major breaking change, with Vue 2's end-of-life set for December 31, 2023. The announcement sent a cascade through JTC's ecosystem.
Mapping the Path to Vue 3
The first task was figuring out when the upgrade could realistically begin. A small virtual team of developers drawn from various teams took on the assessment, ensuring multiple perspectives were represented. They quickly concluded that a monolithic, organization-wide release was impractical. The preferred approach was gradual incrementing — but that comes with costs. Maintaining two supported versions of Vue for essentially the same business features adds time and complexity to every change.
The team mapped the tech stacks for each application and identified potential bottlenecks, making the work widely visible. JTC's flat structure meant internal stakeholders — product owners, architects, and managers — had to be brought on board early. The team also consulted official Vue migration guidance, which pointed to incremental upgrade paths. In particular, Vue 2.7 (codenamed Naruto) backported several Vue 3 features into the Vue 2 line, narrowing the gap between versions.
Not every application in the landscape used Nuxt, and that distinction became important. Nuxt's major version is tightly coupled to Vue's, so a stable Nuxt 3 release was a prerequisite for any Nuxt-based application to migrate. Standalone Vue applications, however, had no such blocker and were ideal first candidates for Vue 3 compatibility.
The Kompas-Next Bridge
With a plan in place, the first real milestone was making the component library compatible with Vue 3 while minimizing duplicated effort. The solution was a second workspace:
We created a new workspace called "Kompas-next" next to the regular components folder, which was scaffolded out using Vue 3. Then we imported the components from the original library.
This approach was feasible because of four enabling factors:
- Vue 2.7 backported enough Vue 3 features — including the composition API — to close the syntactic gap.
- Component syntax between Vue 2 and Vue 3 was no longer radically different.
- Vue Demi allowed components to be converted, one at a time, to be compatible with both versions simultaneously.
- Kompas-next ran isolated tests to ensure stability.
Each component still required slight modification to meet the new standards. But once the work was done, JTC could publish two parallel versions of the component library: Kompas for Vue 2 and Kompas-next for Vue 3. Teams unblocked by Nuxt could now begin migrating their applications.
Distributing the Conversion Work
The investigative groundwork had come from a relatively small team, but the actual conversion work needed broader participation. JTC settled on an agreement that fit its existing contribution model: any developer touching a component that was not yet compatible would convert it to work with both Vue 2 and Vue 3 using Vue Demi, then add the converted component — with tests — to the Kompas-next imports. This rule was communicated early and clearly, and the Kompas-next library grew quickly as a result.
Early adopters — the standalone Vue applications — began migrating their entire codebases to Vue 3 while feeding feedback back into the component conversion process. Seeing the first production applications running Vue 3 was a notable milestone, achieved collaboratively under a unified strategy.
A few components never got migrated through this organic process. The team reasoned that stale development usually indicates stability, so those were migrated by manual assignment instead — close to one-off conversions with little risk. As adoption grew, JTC also started adding Vue 3-specific capabilities to the library, including its own composables, signaling real investment in the new version.
With Kompas-next in place, a significant organizational hurdle was cleared. Teams could migrate to Vue 3 on their own schedules, new applications were encouraged to use the latest standards, and a deprecation path for the Vue 2 codebase became a realistic discussion. JTC aligned Kompas's end-of-life with Vue 2's: December 31, 2023. The work was not finished — but the migration was finally underway, and the organization had a working model for handling major tooling upgrades.
State Management And The Path Ahead
Our e-commerce domain previously leaned on vuex to connect micro-applications by registering stores globally, letting separate apps dispatch actions and share state. That arrangement is being phased out. For internal state we are moving to pinia; for cross-application communication, we no longer treat Vuex as the public interface. Instead we are promoting custom events tied to specific domains. That decoupling keeps us from being locked into whichever state management tool comes next.
Our Nuxt applications are also being prepped for migration. Several modules were built to offload repetitive work such as meta headers, security, and analytics. Those modules are being rewritten as plugins, which reduces the blast radius of the breaking change to only the teams that consume them. Those teams are applying the same incremental strategy at a smaller scale to organize the effort.
What The Upgrade Taught Us
Moving a large shared dependency to a new major version inside a big organization depends less on the specifics of the framework and more on process. The pattern we used for Vue applies equally well to other core architecture pieces. A few principles stood out:
- Keep the transition window explicit and brief.
- Break the work into small, iterative steps and gather feedback from participants early and often.
- Bring key stakeholders on board so the team has enough time and budget to finish properly.
- Pick a rollout strategy that matches your organization’s culture.
- Encourage collaboration and keep communication lines open between teams.
- Take time to appreciate completed milestones, even the small ones.
Maintenance Is A Constant
Upgrading core tooling is not a one-off event. During the State of the Vuenion 2023 talk, Evan You noted that Vue intends to ship releases more frequently in the future, which will continue to affect our codebases. That is manageable now that we have a blueprint for future migrations. The process is repeatable, even if the destination keeps moving.



