Share your feedback
Take a 2-min anonymous survey and tell us what’s working, what’s not, and what matters to you.
Start Survey
I don’t have feedback
A New Standard for MultiversX dApps: Inside SDK dApp v5
A New Standard for MultiversX dApps: Inside SDK dApp v5
Community
July 15, 2025
min read

A New Standard for MultiversX dApps: Inside SDK dApp v5

From planning to implementation

When we started out with the first version of the Web Wallet and the Explorer most operations were done on the Front-End (take for example interpreting transactions). While developing other applications, some parts of the code needed to be reused and some other parts were moved to the API to make Front-End code more efficient. 

At this point, we decided to extract the core wallet logic into a package called @multiversx/sdk-dapp. This was a React-based npm package holding logic to authenticate a user, sign messages and transactions, and provide some UI elements like transaction toasts and transaction listing. This package became the cornerstone of most dApps developed on the MultiversX Blockchain. 

But, as the package grew, it brought with it some shortcomings because we had to adapt it to a wider and wider range of uses like: 

Supporting legacy methods

The main architectural impact on the codebase was maintaining the interaction with the Web Wallet through redirects with URL parameters. Since sdk-dapp supports multiple signing providers, we had to create a unified developer experience (DX) so that when a dApp developer writes some logic for signing and sending transactions he/she is not forced to handle different providers in separate ways. 

The fact that the Wallet interaction triggered a page unload, redirect and reload of the dApp meant persisting the dApp state and relaunching the code from the same point it left off or from a success route (in our case called the callbackUrl). This compromised the user experience (UX) for all the other signing providers which were in-page and could have signed the transactions in a straight-foreward asynchronous mode. 

After a lot of research, we managed at some point to find a new way of interacting with the Wallet, that is through cross-tab communication. This meant that the URL length limit was no longer an issue and that the wallet could be treated just like all other signing providers (ex: xPortal). Unfortunately, the architecture of sdk-dapp had at this point gotten so complex, that changing it would have left us in doubt of making difficult decisions regarding what is still needed and what can be completely overwritten. 

Our new goal was standardizing the signing providers into a single interface.

Supporting multiple technologies

The v.4 version of sdk-dapp package supports all React-based frameworks, that is React.js, Next.js and React Native. 

Given Next.js’s initial rendering mechanism, we had to find a way to make server prerendering not break the app. This again led to a complicated way of writing components.  

Exporting syntax for React components in sdk-dapp

So the goal for us would be to have a base package that can be integrated with most UI frameworks without creating a lot of overhead. This idea came to mind when we had to implement a popup in the middle of a signing flow. This popup was implemented with plain web components and it showed us that we can use plain asynchronous functions to handle business logic that seamlessly blends in with UI.

React-specific problems

One of React’s pitfalls is overuse of the useEffect hook. Since we had to gradually add to our business logic, sometimes useEffect blocks started to make the code difficult to understand. It even made Web Wallet Hub interaction become unstable. To fix that, a review of the entire process had to be done. This set a goal for us to map out processes and make them linear. An example of this will be given below where logic and UI are mixed together to produce a single output of a login function.

Mixing UI and business logic

Since React is mainly a UI framework, it made it convenient for us to use the same package for hosting both business logic and UI components. This made the components very convenient to use in dApps but cumbersome to test in local end-to-end tests inside sdk-dapp. 

From this issue, we decided that if we were to redesign the sdk-dapp, we would split business logic and UI logic into different packages with different responsibilities, making them easier to test in a unit test environment and less dependent on an e2e environment. 

An integrative approach

We know that different developers prefer different technologies. We also know that we invested a lot of time in fine tuning the logic of sdk-dapp to suit our business needs. But if written in React, it could only serve the React-specific ecosystem. Why not open up the gate for blockchain development to other technologies by using agnostic tools? In the next chapter we’ll present the minimal requirements for such tools.

PLANNING THE NEW SDK VERSION

Requirements

Given the above listed requirements, we set out some basic requirements for a new sdk-dapp version that would be similar in concepts to the old one but simpler in usage. Requirements would be:

  • It should be written in TypeScript
  • It should not enforce any framework. Since frameworks become more or less popular over the years, such an approach should ensure its longevity (see axios or lodash as examples)
  • It should handle data storage by using the adapter pattern, so for example in case of React Native, an async data storage could be injected. This would also make testing easier. The store should have some characteristics: it should allow using immutable data, selectors, actions, and be inspectable from browser devtools. State changes should be reactive
  • Data flows should respect the pattern input → async await → output 
  • All providers should conform to a single interface and working with them should not need exception handling
  • UI elements should be written once and used everywhere. They should not enforce a single technology, but rather have a pub/sub communication pattern which allows overwriting them at will as long as the communication interface is respected

Technology choices

These requirements led  to a set of choices, namely:

  • Zustand for state management, since it allows subscriptions to the store for all frameworks and has an integrated solution for react hooks. It also allows setting up any custom persistence mechanism
  • Immer for store immutability
  • All @multiversx packages required for working with signing providers would be integrated under the hood under a single provider class
  • Sencil for creating web components which work universally and also optionally allow deriving React components from the same codebase. UI elements would be hosted in a new package named @multiversx/sdk-dapp-ui, referenced as an optional dependency in sdk-dapp.

PROJECT STRUCTURE

Internal

To make it more lightweight, some helpers used across different packages and dApps that do not implement login and signing were extracted into @multiversx/sdk-dapp-utils package. 

The main parts of the package will be:

  • Store: hosting store initialization, middleware, slices, selectors and actions
  • Providers: hosting provider the class, and all implementations for different signing providers
  • Managers: business logic for UI elements like UnlockPanel and TransactionManager
  • Api Calls: hosting useful methods for interacting with the API
  • Constants: some useful constants from the ecosystem like ledger error codes, default gas limits for transactions etc.

Basic usage

Developers should basically have knowledge about four concepts: 

  • Initializing the network
  • Using the methods or react hooks to display account data
  • Using the Provider class to log in and sign transactions
  • Using the TransactionManager class to send transactions and track the outcome

As said in the introduction, a key change is that interactions between the dApp and the Web Wallet are no longer done through the URL. This means working with accepted providers (Web Wallet, Ledger, DeFi Wallet Extension, Walletconnect (xPortal), Metamask, and Passkeys) is done in the same way. Standardizing the Provider also allows injecting custom providers by adding a providers key to the window.multiversx object. Detailed information about how to create a custom provider will be found in the technical documentation of sdk-dapp.

WHAT’S NEXT ?

What we have already delivered to the community is the updated version of Template Dapp based on sdk-dapp v.5, but also four new templates: Angular, SolidJS, Vue, and Next.JS. Upcoming work will be a new React Native template and moving open source projects like the Lite Wallet, and the Explorer to use the new v.5 version of sdk-dapp. Make sure to check the github repos for more information:

Stay tuned for future updates!

MultiversX Team
MultiversX Team
Published by
MultiversX Team
MultiversX Team
Published on
July 15, 2025
Share this article