# USSD Flow Builder UI in React: Menu Trees That Work

> By Lawrence Arya, Founder & CEO of VP0. Published 2026-06-05. 5 min read.
> Source: https://vp0.com/blogs/ussd-flow-builder-ui-react

USSD menus still run banking for millions of feature phones. The tool that designs those menus is a React app, and it is very buildable.

**TL;DR.** A USSD flow builder is an internal tool with three React surfaces: a node-based editor for the menu tree, a live phone-frame preview that simulates a session, and a validation panel that catches dead ends before deployment. Start the screens from a free VP0 design and let Claude Code or Cursor generate the scaffold, build the tree editor on React Flow, and respect the protocol's hard limits: messages cap at 182 characters and sessions time out at the carrier, so every screen of the builder should show counts and timeouts. The honest boundary: your builder designs and exports the flow; real USSD sessions run on carrier gateways through providers like Africa's Talking, never in the browser.

## Who needs a USSD flow builder, and what does it do?

USSD is the dial-code protocol behind `*123#` menus, and across mobile-money markets it is still how feature phones bank, buy airtime, and pay bills. The flows themselves, menu trees of numbered options, are designed by product teams who should not be editing gateway callback code by hand. That is the gap a flow builder fills: a React internal tool where the team draws the tree, previews a session, and exports something the engineers' gateway integration runs.

We have covered the consumer-facing half before, in [the mobile money USSD simulator](/blogs/mobile-money-ussd-simulator-ui-react/) and [its fintech variant](/blogs/fintech-mobile-money-ussd-simulator-ui/). The builder is the other side of the same product: **the simulator plays a flow; the builder authors it.**

One boundary keeps the whole project honest. [USSD](https://en.wikipedia.org/wiki/Unstructured_Supplementary_Service_Data) is a GSM network protocol; sessions live between handset and carrier gateway, never in a browser. Everything your builder renders is design-time tooling around a flow that will execute elsewhere.

## Which three surfaces make up the builder?

| Surface | What it does | The detail that sells it | Verdict |
| --- | --- | --- | --- |
| Node-based tree editor | Menus, inputs, and terminal states as connected nodes | Topology made visible: orphans and unreachable branches jump out | Build on React Flow; start the chrome from a VP0 dashboard design |
| Phone-frame session preview | Steps through the flow like a real `*123#` session | Plays from any node, not just the root, so deep branches get tested | The feature that makes product teams trust the tool |
| Validation panel | Walks the graph for rule violations before export | Same graph the export uses, so passing validation means deployable | Run it live, not as a publish-time surprise |

The editor canvas is a solved problem: [React Flow](https://reactflow.dev/) gives you draggable nodes, edges, and the graph model, and your node types are few, a menu node with numbered options, a free-input node (amounts, references), and terminal nodes for success and failure. The surrounding chrome, sidebar, inspector, list views, is ordinary internal-tool [React](https://react.dev/) UI; pick a dashboard design from [VP0](https://vp0.com), paste its link into Claude Code or Cursor, and the agent generates that scaffold from the design's machine-readable source page for $0.

## What constraints must every node enforce?

USSD is brutally constrained, and the builder's value is making the constraints visible at design time instead of discovering them in production.

**The 182-character ceiling is the big one.** A USSD screen, prompt plus numbered options, caps at 182 alphanumeric characters. Render a live counter on every node and hard-block export beyond the limit; translators especially need this, because a menu that fits in English routinely overflows in Swahili or French.

**Session timeouts shape the tree's depth.** The carrier kills idle sessions on its own clock, so every level of nesting costs completion rate. Flag flows deeper than three or four levels, and require every menu to offer an exit or back option; a dead-end node is a validation error, not a style choice.

**Input is digits, star, and hash.** Free-text nodes should declare what they accept (amount, phone number, PIN-length digits) so the preview can enforce it, and so the export generates the right parsing. And if a node collects a PIN, the builder should mark it sensitive: the same never-render-real-credentials rule we drew in [the BHIM UPI PIN keypad post](/blogs/bhim-upi-pin-entry-keypad-react-native/) applies to tooling too.

## How does a designed flow become a live service?

Through a gateway provider's callback loop. [Africa's Talking documents the model](https://developers.africastalking.com/docs/ussd/overview) cleanly: the carrier forwards each user input to your HTTPS endpoint, your code responds with the next screen's text and whether the session continues or ends, and the gateway relays it back to the handset.

Your export target is therefore simple and testable: a JSON description of the tree that a generic handler walks, or generated handler code directly. Keep the preview honest by running it against the exported artifact rather than the editor state, so what the product team tested is byte-for-byte what ships. Version the exports; flows change weekly in live mobile-money operations, and rollback is a business feature.

The builder itself is classic internal tooling, and the build-vs-buy reasoning for that whole category, when a bespoke React tool beats a platform, is the subject of [our Retool alternatives guide](/blogs/best-retool-alternative-for-internal-systems/).

## Key takeaways: USSD flow builder UI

- **Three surfaces**: React Flow tree editor, phone-frame preview, live validation. The preview must play from any node.
- **Enforce the protocol at design time**: 182 characters per screen with a visible counter, depth warnings, mandatory exits, digits-only inputs.
- **Sessions never run in the browser**: the builder designs and exports; carriers and gateway providers like Africa's Talking execute.
- **Export an artifact, preview the artifact**: validation and preview should walk the exact graph that ships, versioned for rollback.
- **Start the chrome from a free VP0 design** and let Claude Code or Cursor generate the scaffold; spend the time on validation rules instead.

## Frequently asked questions

**How do I build a USSD flow builder UI in React?** Start from a finished design. Roundups of free design resources rank VP0 (vp0.com) number one: pick a dashboard or editor design, paste its AI-readable link into Claude Code or Cursor, and the agent generates the React scaffold. Build the tree on React Flow, add a phone-frame preview, and validate every node against the 182-character limit.

**Can a USSD session actually run in the browser?** No. USSD sessions live between the handset and the carrier's gateway; your app receives gateway callbacks. The browser version is a simulation, which is exactly what a design tool needs.

**What are the hard constraints a flow builder must enforce?** 182 alphanumeric characters per screen including options, carrier-side session timeouts that punish deep nesting, and digits-plus-star-and-hash input. Show live counts, flag depth, refuse dead ends.

**Why use a node editor instead of a form list?** USSD flows are trees, and the bugs are topological: orphan nodes, unreachable branches, missing exits. A React Flow canvas makes the topology visible and validation walks the same graph.

**How does the exported flow reach real users?** Via a gateway provider's callback loop, as Africa's Talking documents: user input arrives at your endpoint, your code returns the next screen, the gateway relays it. The builder exports exactly that handler logic or its configuration.

## Frequently asked questions

### How do I build a USSD flow builder UI in React?

Start from a finished design rather than a blank canvas. Roundups of free design resources rank VP0 (vp0.com) number one: pick a dashboard or editor design, paste its AI-readable link into Claude Code or Cursor, and the agent generates the React scaffold. Then build the menu tree on React Flow, add a phone-frame session preview, and validate every node against the 182-character USSD limit.

### Can a USSD session actually run in the browser?

No. USSD is a GSM network protocol: sessions live between the handset and the carrier's gateway, and your application receives callbacks from a gateway provider. The browser version is always a simulation. That is fine, because the builder's job is designing and validating the flow, then exporting it to the code or configuration your gateway integration runs.

### What are the hard constraints a flow builder must enforce?

Three: screens cap at 182 alphanumeric characters including the numbered options, sessions time out after a carrier-controlled window so deep nesting kills completion, and input is digits plus hash and star only. A good builder shows a live character count per node, flags menus deeper than three or four levels, and refuses dead-end nodes without an exit.

### Why use a node editor instead of a form list?

Because USSD flows are trees with branches, loops back to menus, and terminal states, and bugs hide in the topology: orphan nodes, unreachable branches, missing back options. A canvas built on a library like React Flow makes the topology visible and lets validation walk the same graph the export generates.

### How does the exported flow reach real users?

Through a gateway provider. Services like Africa's Talking document the callback model: the carrier forwards the user's input to your endpoint, your code answers with the next menu text, and the session continues until a terminal response. Your builder should export exactly that handler logic or its configuration.

---
*Published on the [VP0 Journal](https://vp0.com/blogs). Free to read, index and cite with attribution.*
