Mendix introduced significant changes to its client architecture along with version 10.7.0. The creators moved away from the previously used Dojo Toolkit (a JavaScript framework that gained popularity in the 2000s) and offered a beta version of a new Mendix-React client. In this article, I will discuss the key aspects of this migration and its impact on the development of the Mendix platform. I’ll also show you how to create your own React-based widgets.
If you want to learn more about Mendix, check out our Mendix platform 101: What is it, why is it interesting, and how much does it cost? article. Also, for fundamental information on basic Mendix application development, you can read our detailed Mendix tutorial based on the default (for now) Dojo client.
Reasons for migrating
When it first appeared, Dojo was a solid tool for creating web applications. It significantly streamlined the work of developers and found use in many well-known and respected companies such as IBM, Cisco, and Philips. Unfortunately, over time, this technology failed to maintain its position and became increasingly outdated compared to competing solutions. Dojo’s key limitations include a lack of support for the latest web standards and a smaller developer community, which makes it difficult to find resources and technical support. As a result, competing technologies began to take over its place on the market.
The React library – developed by the Facebook team – was introduced to the market in 2013, which means it’s nearly a decade newer. It’s characterized by high performance and flexibility, and its component architecture allows developers to easily create and manage complex user interfaces. React also offers a wide range of development tools and support from a large and active community. If you want to know about React’s advantages, consider taking a look at my Angular vs React analysis.
The team behind Mendix decided to move away from the Dojo framework and focus on developing a new client based on React. The idea was to improve application performance and provide access to React’s modern features. According to the official resources, the migration in fact resulted with at least a few useful changes. In my opinion, they can be reduced to three main aspects: performance improvement, support for incremental page loading, and a more future-proof nature.
Performance improvements
The Mendix team rightly notes that performance is one of key areas in application development. If your page loads too long, works slowly, and forces the user to look at a white page for a long time when initializing, this can lead to the user losing interest or choosing another solution. Performance is also important for internal applications because the faster a system works, the less time employees lose. Moreover, people don’t like working with slow, unoptimal tools, so employee satisfaction is another consideration.
Tests performed on applications created with the old Dojo client and new React one indicate significant benefits of using the latter (tested with Lighthouse):
As you can see, the React-based client runtime is noticeably faster in almost every way. The Mendix team believes that the Largest Contentful Paint is the most important test – it describes the situation when your application has mostly loaded successfully. Looking at the above table, you’ll notice that the React client has a significant impact on LCP (around 10% improvement). This is even more significant when you realize that these improvements were achieved without any performance optimizations – this is the effect of the migration alone.
Support for incremental page loading
React client’s second advantage is the option to use incremental page loading. In the case of the previous client, the user saw a blank page with a loading indicator until the page’s full content was loaded. This isn’t optimal for UX (User Experience). With the new client, the page’s basic structure is shown immediately, and the content is added as it loads. This lets users see some of the loaded data in advance and familiarize themselves with the app’s interface. It’s mainly a psychological difference but it significantly improves the perceived fluidity and efficiency of your application.
Future-proof nature
Mendix has been working on migrating from Dojo to React for a long time. This involved maintaining the ability to work with both solutions, and thus storing the various libraries required for this. Switching to the new client allows them to clean up the platform and remove many libraries that are no longer needed. Additionally, it allows you, as a developer, to use the latest solutions supported in the web browsers. This means better stability and security of your Mendix applications.
Requirements for using the React client
The React-based client is still in the beta phase, but with version 10.18 it’ll be released as a generally available opt-in feature (and, considering the abovementioned benefits, with time, Mendix Team aims for it to become the default option). To use it, you just need to change the configuration in App Settings Runtime and set the Use React Client option to Yes.
However, if you plan to migrate your application from Dojo Client, there are also some key requirements and compatibility considerations you should be aware of before taking this step.
APIs that are no longer supported
The first key piece of information is the end of support for many APIs that were previously widely used. These include:
- The global symbol dojo
- The global symbol dijit
- The setting mx.modulePath
- The function mx.ui.openForm
These APIs were related to Dojo and no longer will be supported with the new React client. You can find more information about React and available APIs in the official documentation.
Widget requirements
Next, you need to take care of the widgets. In order to convert a Dojo widget into a React one you need to utilize JavaScript programming. A widget needs to meet two requirements to work with the React client:
- It must be a pluggable widget
- It must be compiled using the pluggable-widget-tools version 9.4.1 or above
Unsupported components
Currently, not all Mendix components from the Marketplace work with the new React client (but Mendix’s developers are rewriting them to React – it’s an ongoing process). You can check the current status of the most popular widgets on this page. Of course, if you are unable to find a module that meets your requirements or an existing component you need has not yet been adapted to the new client, you can always create a Custom Widget (more on this in the next chapter).
Migration mode
Due to the abovementioned limitations, simply migrating your app probably isn’t the best idea. Before you select the React client, you should check out the Migration mode option first. It will display warnings (instead of errors) for all incompatible widgets found in your project. It’s a helpful tool that allows you to explore and test the React client without the risk of blocking the application’s operation due to errors. Set the Use React Client option to Yes only after meeting all the requirements described above and resolving the warnings.
Creating a custom Pluggable Web Widget with React
I mentioned above that the React client only supports so-called Pluggable Web Widgets. These are just a new version of the custom-built widgets available in Mendix up until now – the main difference is that they’re made using React instead of Dojo.
The goal for this section is to show you how to create such a pluggable widget that will work with the new client, and allow you to add a simple input field. The following guide assumes that you already have knowledge of HTML, CSS, JavaScript and React, so I won’t explain how individual code elements work.
First, you will need to create a new folder in which you will create your widget, open it in your selected IDE (I use Visual Studio Code) and install the following libraries:
To make things easier, once you have downloaded Node.js, you can use the following command in terminal to download the remaining items:
npm install npm@latest -g npm install yo -g npm install @mendix/generator-widget -g
After downloading all dependencies, you can start creating your widget. To do this, generate a new widget using Mendix. Use the following command:
yo @mendix/widget MySimpleInput
As a result, the generator will ask you questions about your module during setup. Complete them according to your needs (below are the details used for this guide’s purposes):
Widget name - Name of your new widget Widget Description - Description of your new widget Organization Name - Name of your organization Copyright - Your copyright information License - Your license Initial Version - initial version number of your project Author - Name of the author Mendix App path - Path to your Mendix Studio Pro project's location Programming language - JavaScript ES6 / TypeScript Which type of components do you want to use? Function Components / Class Components Widget type - For web and hybrid mobile apps / For native mobile apps Widget template - Full Boilerplate (recommended for beginners) / Empty widget (recommended for more experienced developers) Unit tests - Yes / No End-to-end tests - Yes / No
If you performed all actions correctly, you should see the following message in the terminal:
Widget successfully built!! Please open Mendix Studio Pro and start playing with your new widget.
If you look at the File Explorer in your IDE, you’ll notice that the generator has created all the files needed to create the widget. If you’ve worked with React previously (and I assume you did), you may be familiar with many of these. However, there are also a few new items you probably haven’t seen before:
Let’s analyze what’s the purpose of the files and folders shown above and what information is contained within them:
- dist – this is where your built and bundled code will be outputted
- node-modules – the folder containing node dependencies of your application
- src – the folder containing the source code of your application
- components – the folder containing the JSX code of widgets you are creating
- ui – the folder containing the CSS sheet for styling the widget
- package.xml – describes the structure of the package containing your widgets
- MySimpleInput.editorConfig.js – the config for the preview in Design Mode in Mendix Studio Pro
- MySimpleInput.editorPreview.jsx – the component that provides the preview in Studio Pro
- MySimpleInput.jsx – the entry point for the widget
- MySimpleInput.xml – the markup which describes the interface between the widget and Mendix
- package.json – the file describing all of the widget’s dependencies
- prettier.config.js – the file which allows you to configure prettier rules for your code
Okay, you have successfully created your new widget files. The next step is to build a widget package based on them, containing information about your widget. You can do this by running the following command in the terminal in the root folder of your application:
npm run build
Now, if you look inside the dist folder, you will notice that there is a new .mpk file containing the created widget. Now, you simply need to upload it to your Mendix application.
Adding a new custom widget in Studio Pro
Creating a blank app
To test the functionality of your new widget, you need to add it to your Mendix application. I will create a new blank application for the purposes of the guide. If you have an existing application to which you want to upload your widget, simply skip these steps and go directly to the Uploading the widget section below.
To create a new application, go to Create a New Application page in Mendix and select Blank Web App as shown below:
Choose Studio Pro as the Template version:
And then name your application:
Please note that I am working on Studio Pro 10.11 for the purposes of this tutorial, so some of these screens might look different for you if you’re working on a different version. You can easily find all the necessary information in the official documentation.
All that is left for you to do now is opening the newly created project in Studio Pro. Once you have done that, we can proceed to loading our widget.
Uploading the widget
If you are working on an existing Mendix application (you didn’t create a new project), you’ll need to refresh the system files that Studio Pro sees. Press the F4 key or select App > Synchronize App Directory from the menu bar.
Then follow these steps:
1. Open the Home_Web file in the Page Editor.
2. Open the Toolbox on the right side of the screen and search for your new widget. You can use the search box or find it on the list (it should be at the end).
3. Drag your widget to the desired location on the page, just like you would with any other widget.
4. Run the application and open it in your browser. Your new widget should display the Hello message.
You can add something to the message to ensure that the parameters are passed correctly from the modeler to the widget on the frontend.
To do this, double-click on your widget located on the Home Page and add any text (like on the image below):
As a result, when you go to your application in the web browser, you should see the updated version:
Congratulations! You’ve successfully added a new custom widget to Studio Pro and displayed it in your own application. I’ll now show you how to modify the widget to add a custom input to the page. However, before I do that, I suggest you make one change to make things easier in your work.
Adding automatic reload during development
Although the current method of deploying and testing changes made to your widget works, it’s quite slow. You can improve it a bit by completely refreshing the page and clearing the cache after each change. Otherwise, the browser will not display the changes you have made.
But there’s another way – one that I personally prefer. You can disable the cache in your browser while you work. All you need to do is open the Network tab in the developer tools of the selected browser and select the Disable cache option.
It’s important to remember that if you close the developer tools, this change (disabling the cache) will stop working. For this reason, I suggest opening the tools in a new window so that they remain open in the background all the time.
The last step is to start the server of your widget using the command:
npm run start
Now, every change you make will be reflected in the browser. You can easily see this for yourself by modifying the text displayed from the HelloWorldSample.jsx file.
Modifying passed data and updating widget definition file
Now, let’s modify the code of your widget so that it returns the number input. To do this, you need to go to the MySimpleInput component and make modifications to its code. But first, take a look at the current code that is in this file:
import { createElement } from "react"; import { HelloWorldSample } from "./components/HelloWorldSample"; import "./ui/MySimpleInput.css"; export function MySimpleInput({ sampleText }) { return <HelloWorldSample sampleText={sampleText} />; }
This is a simple component that accepts the sampleText parameters from the configuration that you modified in StudioPro, and then passes it to the HelloWorldSample component. Since you no longer need it, you can safely remove the HelloWorldSample component, and call this sampleText, e.g., numberInput. Since the logic that you will create isn’t complex, you can include everything in MySimpleInput. The next step will be to change the values passed from StudioPro to your widget. You no longer want to receive a text value, but a number – that’s why you changed the name of params. In order to do that, you need to update the Mendix Widget Interface.
You can find this interface in the MySimpleInput.xml file, i.e., the so-called widget definition file. You need to modify it so that, instead of a string of characters, it only accepts numbers. You can also modify the name of the tab in which you will set your parameter. To do this, just change the value in the caption in propertyGroup to, e.g., Data source. It’s also worth remembering to check if the pluginWidget parameter is set to true. This is the flag responsible for ensuring that the widget will be generated as a new Pluggable Web Widget using React. The final appearance of the file after making changes should look like this:
<?xml version="1.0" encoding="utf-8" ?> <widget id="pretius.mysimpleinput.MySimpleInput" pluginWidget="true" needsEntityContext="true" offlineCapable="true" supportedPlatform="Web" xmlns="http://www.mendix.com/widget/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mendix.com/widget/1.0/ ../node_modules/mendix/custom_widget.xsd" > <name>My Simple Input</name> <description>My widget description</description> <icon /> <properties> <propertyGroup caption="Data source"> <property key="numberInput" type="integer" required="true" defaultValue="5"> <caption>Initial Input Value</caption> <description>The initial value of the input</description> </property> </propertyGroup> </properties> </widget>
Next, you need to synchronize your application in StudioPro using F4. Thanks to this, when you open the MySimpleInput widget settings, you should see the appropriately modified appearance of the tab.
After making all the above changes, you can go back to the browser tab with your application. Now, when you look at its appearance, your eyes will see the default input value that you set in StudioPro:
Creating custom React logic inside Pluggable Web Widget
We can now move on to the last, but crucial part, which is implementing the custom logic of the component. To do this, go back to the MySimpleInput.jsx file, which contains all the logic of your newly-created widget. This is where you need to add and handle your input. To do this, simply modify the code as follows:
import { createElement, useState } from "react"; import "./ui/MySimpleInput.css"; export function MySimpleInput({ numberInput }) { const [count, setCount] = useState(numberInput); return ( <div> <h4>Enter Number Value</h4> <p>{count}</p> <input onChange={e => setCount(e.target.value)} value={count} type="number" /> </div> ); }
After rebuilding the application, you can return to the browser and see what impact your changes had on the appearance of the application. The result is a fully functioning input.
Summary
Moving away from the Dojo framework to React translates into a number of benefits – from optimizing the platform’s performance to the ability to use the latest standards and solutions. It also significantly increases the platform’s accessibility for most developers since React is currently so popular that it’s hard to meet a developer who isn’t familiar with it. This means that now this huge group of developers can start creating new content (in the form of widgets) in StudioPro relatively quickly.
In addition, the process of integrating React-based components I presented above shows how easy this really is. Thanks to tools prepared by the Mendix team, such as Yeomani Mendix Pluggable Widget Generator, you can quickly generate a new widget project, and after performing a short configuration, start using your new widget within the application. With just these few steps, you can employ your experience with React to create new functionalities or extend existing ones. You only need to remember to pass new parameters using an XML file, and the rest is based purely on React, which significantly lowers the entry threshold.
That’s about it for this article. If you’re interested in the Mendix platform (and other low-code tools), check out other publications on our blog:
- Mendix platform 101: What is it, why is it interesting, and how much does it cost?
- Mendix tutorial: Start making apps using a powerful low-code platform
- Oracle APEX tutorial: Uncover Oracle’s best-kept low-code secret
- OutSystems tutorial: Learn low-code development and get your first certificate
- OutSystems application development: First steps