ICX-React: Bringing React.js to a Decade-Old Knockout.js Framework

14 Apr 2025

Integrating React.js into Integro CX

Integro CX

The front-end team at Dunstan Thomas embarked on a major R&D project: integrating React.js into our proprietary low-code framework, Integro CX (ICX). Originally built with Knockout.js over a decade ago, ICX powers numerous client applications today. Our goal was to modernise its front-end rendering while preserving as much of the existing architecture as possible.

This blog outlines the challenges, solutions, and milestones of our ICX-React journey.

What is Integro CX?

Some examples of Integro CX systems Integro CX is a low-code framework that dynamically loads UI definitions at runtime. It utilises hash routing to determine navigation and relies on separate, pre-compiled JavaScript layers for UI components. These components, ranging from simple text inputs, or colour pickers to complex grids, are dynamically validated, rendered, and controlled by a built-in rules engine.

ICX’s unique runtime loading and lack of a compilation step presented significant challenges in introducing React while maintaining performance and compatibility.

The goals of ICX-React

Our mission was to integrate React into ICX without a full rewrite. Instead, we aimed to:

  • Retain existing logic and APIs
  • Enable React and Knockout.js to coexist
  • Maintain runtime loading and lazy loading of components
  • Transition from Object-Oriented Programming (OOP) to Functional Programming (FP)
  • Ensure styling compatibility across client projects
  • Optimise performance for a hybrid architecture

Challenges and solutions of modernising tech

Mixing old and new technologies

Rather than rewriting ICX from scratch, we decided to embed React into our existing stack, which includes Knockout.js, CoffeeScript, and RequireJS. We incorporated the RequireJS JSX plugin to load React files and introduced a React entry point (App.jsx).

To facilitate communication between legacy and React code, we leveraged ICX’s existing Model-Command-View-Signal (MVCS) architecture. Specifically, we used event buses ("signals") to update React component props dynamically. This allowed React components to integrate seamlessly with ICX’s legacy boot sequence and logic. Using the React component inspector in ICX.

Using the React component inspector in ICX.

Maintaining runtime loading and build structure

ICX’s runtime loading meant we couldn’t precompile everything into a single React-based app. Instead, we structured our build system using RequireJS to separate React and Knockout.js components.

We wrote a DataComponentContainer.jsx component to handle lazy loading of components via promises. When loading a component, it detects whether it is a React or Knockout.js component:

  • React components: Loaded and rendered directly.

  • Knockout.js components: Wrapped in a React container, where ko.applyBindings manages them. We also hooked into React’s lifecycle to properly dispose of Knockout components on unmount.

This hybrid approach ensured that legacy components remained functional while allowing new React-based components to be introduced gradually. Before (left - Knockout.js) and after (right - ICX-React) image of an ICX implementation of a client details form

Reviewing visual differences of a knockout component converted to React.

Ensuring UI Consistency and Styling Compatibility

To maintain visual consistency, we preserved ICX’s DOM structure as much as possible. This ensured that existing styles and branding remained compatible without requiring any CSS rewrites.

We used our automated screenshot-based testing framework, FETest, to verify UI consistency. FETest runs Cypress in a docker container and captures screenshots at different screen sizes, then compares them to baseline images from the legacy ICX system. Minor pixel differences due to React’s whitespace handling were acceptable, but larger differences indicated areas needing refinement.

Transitioning from OOP to FP

ICX’s legacy Knockout.js components relied on OOP inheritance via a BaseDataComponent class. Since React favours a functional approach, we replaced this with a custom React hook, useBaseDataComponent, to manage shared behaviours such as validation and event handling.

To validate this approach, we fully converted the TEXTBOX component from Knockout.js to React, ensuring it retained all expected features. This laid the foundation for future data component conversions.

Feature Deprecation and Cleanup

ICX has accumulated numerous features over the years, some of which are rarely used. During the React transition, we systematically reviewed features, tagging candidates for deprecation. We collaborated with stakeholders to confirm which features were safe to remove, ensuring we focused only on essential functionality. The custom Azure DevOps dashboard we used to track our progress and deprecations.

The custom Azure DevOps dashboard we used to track our progress and deprecations.

Performance Considerations

The hybrid approach introduced additional complexity, raising concerns about performance. We conducted comparative tests by running the Wealth client project in both legacy Knockout.js ICX and ICX-React.

Using QuickTime and iMovie, we recorded and analysed startup times and navigation speeds. The results showed:

ICX-React startup was 145% faster than legacy ICX. Navigation was 216% slower in ICX-React due to increased processing overhead.

Despite the slower navigation, the team concluded that ICX-React remained viable for production use, given the benefits of modernization.

Key milestones achieved

  • Initialised React within the existing tech stack
  • Rendered Wrapper SPA using React
  • Integrated mixed Knockout.js and React components
  • Successfully loaded and rendered data components dynamically
  • Developed a React version of the WizardFormApp
  • Implemented validation and rules for React components
  • Ran FETest for automated UI verification
  • Validated performance and confirmed feasibility
  • Successfully ran the Wealth project in ICX-React

Successful React.js integration

By the end of this project, ICX-React had successfully integrated React into our low-code framework, demonstrating its feasibility and setting the stage for continued development. While challenges remain, particularly around performance optimisation and further component conversions, our hybrid approach has proven effective in modernising ICX without a disruptive full rewrite.

This project has reaffirmed React as the future of ICX, enabling us to leverage modern development practices while maintaining compatibility with our legacy systems.

Previous Article

Dunstan Thomas Products Contact Us

Gavin Jackson
Head of Frontend Engineering at Dunstan Thomas