UX Bounty - Request for Feedback: A Unified UI Component Library

Hey Polkadot community! :waving_hand:

As a contributor of the UX Bounty initiative, I am working on UXB-7: Unified UI Library in order to create a shared, extensible, and developer-friendly UI component library aimed at improving the frontend experience for Polkadot and Substrate-based dApps.

The goal is to create a flexible, open-source library that:

  • Avoids reinventing the wheel by building on existing libraries (papi, reactive-dot, dedot, …)
  • Supports both Substrate (first) and Polkadot Hub (+EVM-based later)
  • Gives developers full control over their UI components
    (inspired by shadcn/ui, not only themable but able to control every aspect of the components)
  • Encourages community alignment around best practices and UI patterns
  • Aligns with the UX Bounty goals to improve Polkadot UX through best practices and standards

Problem Overview

Building components for Polkadot frontend applications that can read or mutate chain state is not a simple task as many states must be taken in account of and modeled. For example a button for submitting transactions will have to account for states aligned to the questions:

  • Is the a wallet installed and connected to the app? (disabled?)
  • Does the user have enough tokens to pay for the fees? (read account balance / estimate fees / disable? / error message)
  • Is the websocket / lightclient connection active and connected to the correct chain? (switch network? / info message / await connection)
  • Clicking the (enabled) button must interact with the browser extension’s signer to ask for confirming the transaction. (wallet interaction)
  • After signing a tx, should it show a loading and a complete state? (monitor events)
  • Trigger a notification toast informing about the progress? (interact with other components)
  • If errors occur somewhere in the process, the user must be informed (error handling and display)

If not all possible states are managed in a component, UX wil suffer. The above is just one example and many more exist, e.g. amount inputs or address inputs that need to be validated and eventually read chain state. To rebuild all that logic and components for every app from scratch places a huge burden on frontend developers.

Planned Approach

We plan to start small - focusing on proving value with a minimal, core set of components rather than aiming for a full design system from day one - while continuously incorporating community feedback. Inspired by the shadcn/ui philosophy, developer flexibility and modifiability are top priorities: we aim to provide modern DX with full control and components that can be added to the codebase via a cli (e.g. npx polkadot-ui add txbutton). As a result every aspect of the component can be changed.

Existing libraries should be evaluated and only excluded with clear justification and a plan to replicate relevant functionality. Where possible, we will decouple from hooks libraries, allowing for flexibility in using alternative libraries. We will avoid reinventing components by researching existing solutions, and any deliberate exclusion will be documented alongside an improved alternative.

The goal is to build a small v0 UI component library usable out of the box, with a focus on Substrate support initially while eventually covering both HUB (EVM) and Substrate ecosystems.

This effort will also compile prior UX Bounty work - such as the UX glossary - into reusable React components, helping establish best practices and long-term alignment with the broader builder ecosystem, particularly the HUB direction.

Phase 1 - Foundation, Research, RFC (current)

  • collecting community feedback and doing research on existing component libraries in the ecosystem
  • reach out to different ecosystem actors and testing existing solutions

Phase 2 - Proof of Concept

  • create a minimal react component library that showcases the feasability of the chosen approach that offers a proof of concept
  • 1 demo component (the one with most upvotes from here) with cli to add to a react application

If Phase 2 is successfully completed and the community affirms the approach, more components can be developed in

Phase 3 - Component Library

  • Creating 5 more components based on figma UX flow
  • Documentation
  • incorporate feedback from ux researchers, community and apply best practices from UX Bounty (glossary, tooltips)

:magnifying_glass_tilted_left: What We’re Evaluating

Many components in the library will need access to chain state, extension accounts, and transaction capabilities. To enable this, the library will ship with a context and provider layer (based on existing solution where available) that connects to the blockchain via either WebSocket RPCs or light clients like smoldot (papi, dedot), and to browser extensions for account management.

We’re actively reviewing current libraries in the ecosystem in order to find the best possible approach and architecture, including:

For a more complete list of component libraries available in Polkadot and beyond, see the notion page: the UXB-7 Inified Ui Library.

:folded_hands: How You Can Help

We want your input! Whether you’re a dApp builder, designer, or just UI-curious:

  • What components do you need most? (:ballot_box_with_ballot: vote and propose here)
  • Which of the above libraries do you currently use, and why?
  • What are the pain points when building UIs for Polkadot/Substrate dApps?
  • Do you prefer modular approaches or more opinionated component kits?

Your feedback will help shape priorities and design decisions as we head into initial development in Phase 2, if there is positive feedback by the community. The goal is to provide a library that’s not only usable but actually used and that means it needs to reflect the real needs of frontend developers in the Polkadot Ecosystem.

Please reply here, help us prioritize components or reach out if you’re interested in contributing, testing, or just sharing ideas.

Looking forward to hearing your thoughts!

  • Twitter / X: @niftesty
  • Telegram: @niftesty
  • Discord: @niftesty
  • Matrix: @eennoo:matrix.org

Looping in some ecosystem members who may be interested in this project or have interesting context
@ross @tien @josep @olanod @Remy_Parity @sinzii @voliva @Karim

16 Likes

Thanks for sharing this — it’s a good initiative and something that aligns with what we’d like to do through the Pop CLI.

We would like to add optional frontend templates to every chain and contract template offered by the CLI. These templates would provide developers with full-stack starting points that demonstrate how to interact with on-chain storage, extrinsics, and smart contracts using libraries like papi or dedot. Each would be paired with a tutorial to help developers get started quickly and extend confidently. All with the goal to offer one tool for everything you need for Polkadot Development.

Importantly, we’re not aiming to build all these frontends ourselves. If high-quality, community-built templates or component libraries like the one you’re working on already exist, we’d love to integrate them directly into the CLI and contribute to their ongoing improvement. Our goal is to avoid duplicating effort, align with best practices, and ensure developers have an excellent experience.

We’d love to open up a conversation around how integration could look in practice — including timelines for delivering the unified UI library and our frontend templates — so both sides can align and get the full picture.

Daan | R0GUE

5 Likes

Thanks for the comment. The timeline for this is to wait 3 weeks for community feedback and if positive, build a small working prototype with cli + 1 component. The timeline for prototype (Phase 2) + finished working library (Phase 3) is ~2 months so end of August is a realistic estimated.

I think Templates + UI components is a very good match as can be seen in many github templates for different frameworks. I can see that many teams are working on frontend templates or planing them at the moment [1] and I think it is a logical next step after the underlying library infrastructure (papi, dedot, reactive-dot) has reached its current production ready state. Ideally templates can make use of the components from the planed library (e.g. TransactionNotification), therefore save time and instead focus on infrastructure [2]

[1] e.g. create-polkadot-app, a Polkadot Open Source Grant application, inkathon2
[2] e.g. templates for different frameworks or for special libraries, e.g. ink smart contracts with papi ink sdk

3 Likes

As I’m tagged I’ll share our approach :slight_smile: Virto is currently focused on creating high level UI components as a way to package more complex functionalities provided by pallets and runtime components our chain and others in the ecosystem can integrate like virto-connect that abstracts the usage of pallet-pass, nft memberships with prepaid gas, sessions, transaction extensions and passkey signing to give the end user a simple to reason with product: copy-paste a couple of lines and I get this component in my page/store/app that allows users to login and send transactions like its web2.

As technology of choice I went for standard vanilla web components, they are not the most common choice as they can be a bit verbose but in 10 years when hundreds of JS frameworks would have vanished the browsers will still support the resilient standards based web components that can integrate with any framework(or none at all). Having a declarative nature I think it also helps in the age of AI where front-ends will be generated by non technical users and their bot of choice can change some behavior updating an html attribute the prompter will understand, which brings me to …

Defining an audience is important, I’m more inclined to step out of our web3 bubble so I avoid UI elements that scream blockchain like a network selector, anything showing addresses, creation of extrinsics, etc. Instead we target less technical people like founders or someone using a website builder who have a concrete use case in mind, e.g. I need a shopping cart and checkout, a payment button, a chat prompt aware of currency amounts or user aliases, a discussion thread, etc. So it might be worth dividing components by use cases(financial, commerce, socials, media, etc.), such components will be more complex and might require things no yet available in our blockchains but definitely more useful if the target is to get people to create actual products.

7 Likes

Thank you for your input. I will consider web components too. Also great work on virto-connect, nice UX.

From my experience it is mostly the products themselves that will provide drop in composite components that allow devs to connect to their services, e.g. RainbowKit on ETH for their <ConnectButton> component or CoinBase’s <Buy> component to purchase a token, or your own virto-connect too?. Those components leverage the products own apis / services by providing a quick way for devs to use their components and as a result for the users too that use the dev’s apps.

What we are aiming at here is a lower level. Generic components, e.g. amount inputs, transaction notification components that might be reusable across many applications - beyond specific use cases (e.g. financials, socials, …)

3 Likes

As someone who’s tinkered with Polkadot, I’ve got to say, some things that should be simple like setting up basic wallet connections or using WalletConnect, ended up taking more time than I would have liked. I think this could be a really cool library which can save teams time doing non-trivial work, leading to teams spending more time on the nitty, personalised aspects.

As for @olanod’s comment, I agree. I’ve never liked seed phrases (most of my friends still only use variations of the same password, how can they be trusted with a seedphrase), “Wallets”, or most Web3 quirks, they always felt like they were designed to stand out just for the sake of being different, or maybe because they were mainly built with developers in mind, not everyday users. In reality, they just made the space more confusing than it needed to be. In saying this, I think this is still needed and many aspects can be future proofed.

2 Likes

Hey @niklasp, this is a great idea! I’d really love to see us create a shared and unified set of components that dapps can build upon and reuse—so developers don’t have to rebuild everything from scratch every time they start a new project.

That said, one of the challenges I see is designing abstractions flexible enough to work across different libraries. A couple of examples:

  • Components like NetworkSelect or NetworkIndicator are commonly used in dapps. But how do we expose an API that supports various JSON-RPC providers (e.g., dedot or papi)? For instance, changing the network usually requires initializing a new WebSocket provider and emitting connection statuses (e.g., connected, disconnected) to inform the NetworkIndicator component.
  • For WalletConnect components, could we support opt-in usage of existing wallet connector solutions in the ecosystem—such as SubConnect or TalismanConnect? This would give dapps the flexibility to choose which connector best suits their needs.

I understand this will require a careful balance when deciding what to support and what not to—but I’d love to hear your thoughts on it.

Another component I believe we’ll need is AccountSelect. When users connect a wallet with multiple accounts, they should be able to choose and switch between accounts/addresses to interact with networks in dapps. In addition, it would be helpful to display the free balance of the selected account. If the balance is too low to cover transaction fees, we could show a warning or hint to inform the user. This functionality may go hand-in-hand with the WalletConnect component, so I just wanted to flag it here in case you already have something like this planned.

On the template side, we’re also building Typink, a toolkit for ink! dapps that includes React hooks and a CLI for bootstrapping new projects, with options to select supported networks and wallet connectors. We also provide a transaction notification utility so devs can easily show transaction lifecycle statuses.

We’d love to explore how we can integrate the unified/shared components into Typink’s templates to avoid duplicated effort and optimize UX for dapps built with Typink!

Thang Vu - Dedot Team

1 Like

Thanks for your comment. Yes it will be the hardest part to abstract. It would be perfect to rely on other libraries for providing all relevant extension- and chain-connection logic so the component library can focus on components + hooks for calling those. As I imagine the library cli based, arbitrary files can be added to the code base of the developer. It would be perfect to have the following files

In the end the cli will probably need to offer options, e.g. papi + reactive-dot or dedot + X. I imagine a similar structure like below would be added to the repo (subject to change + discussion).

/app
├── ...
├── config.ts
└── polkadot-ui
    ├── providers.tsx
    ├── hooks
    │   ├── use-block-number.ts
    │   ├── use-connection-status.tsx
    │   ├── use-identity-by-display-name.ts
    │   └── use-identity.ts
    └── components
        ├── address-input
        │   ├── address-input.tsx
        │   └── util.ts
        └── another-component
            └── another-component.tsx

That way only the files in the /hooks folder, the library config and providers would need to be altered. In any case all files can be adapted for maximum flexibility but of course it should work out of the box too.

Shadcn also developed a component registry schema that could be followed.

It’s a little bit too early to decide the full architecture and we are waiting until next monday on community feedback and then decide how to proceed. The next step would surely be a working prototype where devs can test the cli and give feedback.

Very open to discussions! The goal is to provider good and simple tooling to make frontend dev’s lifes easier while providing default components with good UX. win-win

I will have a look at Typink and the tx notification utility and start hacking with it. It would also be nice to define a standard there too for the best DevX and UX.

1 Like

Hey hey,

Coming from the Eth dev world, a library like wagmi (which you mentioned) for Polkadot would be a complete game-changer.

If you’ve ever built a dApp on Ethereum, you know what a huge pain it used to be. You’d have to create your own “Connect Wallet” button and then manually add support for every single wallet out there… MetaMask, WalletConnect, and the other 293829832 options. It was a nightmare.

Then wagmi came along and fixed all that. You plug in their library, and boom, you magically support a ton of wallets right out of the box.

But it’s not just about connecting wallets. They give you a whole bunch of super useful React hooks to do pretty much anything you need: fetch balances, call contracts, ask a user to sign something, etc. It just works, it’s modular, and it makes building stuff so much faster.

This is exactly what Polkadot needs. A library like that would be a fantastic starting point. It would make building dApps way easier and would be a massive boost for the whole ecosystem.

7 Likes

Heyhey, thanks for your comment I agree and I think papi, dedot and reactive-dot do a good job in providing the logic wagmi offers. Especially reactive-dot with e.g. useAccounts, useMutation, …

This initiative is more on the component side while it would rely on hooks from other libraries and only add or compose new ones when needed. That said, I think there is room for collaboration and synergies but moving hooks to a hooks library and maintain them separately would surely be better imo.

To onboard app developers i think we additionally need:

  1. hook libraries for reading + mutating chain state (eventually abstractions that help devs not needing to know specific extrinsics for e.g. staking)
  2. component library making use of those hooks
  3. templates using the components + hooks
5 Likes